Step 5: Devise test cases

With the inputs, outputs, and boundaries properly dissected, we can generate concrete test cases. Ideally, we would combine all the partitions we’ve devised for each of the inputs. The example has four categories, each with four or five partitions: the str category with four partitions (null stringempty stringstring of length 1, and string of length > 1), the open category with four partitions (the same as str), the close category with four partitions (also the same as str), and the (stropenclose) category with five partitions (string does not contain either the open or close tagsstring contains the open tag but does not contain the close tagstring contains the close tag but does not contain the open tagstring contains both the open and close tagsstring contains both the open and close tags multiple times). This means you would start with the str null partition and combine it with the partitions of the openclose, and (stropenclose) categories. You would end up with 4 × 4 × 4 × 5 = 320 tests. Writing 320 tests may be an effort that will not pay off.

In such situations, we pragmatically decide which partitions should be combined with others and which should not. A first idea to reduce the number of tests is to test exceptional cases only once and not combine them. For example, the null string partition may be tested only once and not more than that. What would we gain from combining null string with open being null, empty, length = 1, and length > 1 as well as with close being null, empty, length = 1, length > 1, and so on? It would not be worth the effort. The same goes for empty string: one test may be good enough. If we apply the same logic to the other two parameters and test them as null and empty just once, we already drastically reduce the number of test cases.

There may be other partitions that do not need to be combined fully. In this problem, I see two:

  • For the string of length 1 case, given that the string has length 1, two tests may be enough: one where the single character in the string matches open and close, and one where it does not.
  • Unless we have a good reason to believe that the program handles open and close tags of different lengths in different ways, we do not need the four combinations of (open length = 1close length = 1), (open length > 1close length = 1), (open length = 1close length > 1), and (open length > 1close length > 1). Just (open length = 1close length = 1) and (open length > 1close length > 1) are enough.

In other words, do not blindly combine partitions, as doing so may lead to less relevant test cases. Looking at the implementation can also help you reduce the number of combinations. We discuss using the source code to design test cases.

In the following list, I’ve marked with an [x] partitions we will not test multiple times:

  • str—Null string [x], empty string [x], length = 1 [x], length > 1
  • open—Null string [x], empty string [x], length = 1, length > 1
  • close—Null string [x], empty string [x], length = 1, length > 1
  • str—Null string [x], empty string [x], length = 1, length > 1
  • (stropenclose)—String does not contain either the open or the close tag, string contains the open tag but does not contain the close tag, string contains the close tag but does not contain the open tag, string contains both the open and close tags, string contains both the open and close tags multiple times

With a clear understanding of which partitions need to be extensively tested and which ones do not, we can derive the test cases by performing the combination. First, the exceptional cases:

  • T1: str is null.
  • T2: str is empty.
  • T3: open is null.
  • T4: open is empty.
  • T5: close is null.
  • T6: close is empty.

Then, str length = 1 :

  • T7: The single character in str matches the open tag.
  • T8: The single character in str matches the close tag.
  • T9: The single character in str does not match either the open or the close tag.
  • T10: The single character in str matches both the open and close tags.

Now, str length > 1, open length = 1, close = 1 :

  • T11: str does not contain either the open or the close tag.
  • T12: str contains the open tag but does not contain the close tag.
  • T13: str contains the close tag but does not contain the open tag.
  • T14: str contains both the open and close tags.
  • T15: str contains both the open and close tags multiple times.

Next, str length > 1, open length > 1, close > 1 :

  • T16: str does not contain either the open or the close tag.
  • T17: str contains the open tag but does not contain the close tag.
  • T18: str contains the close tag but does not contain the open tag.
  • T19: str contains both the open and close tags.
  • T20: str contains both the open and close tags multiple times.

Finally, here is the test for the boundary:

  • T21: str contains both the open and close tags with no characters between them.

We end up with 21 tests. Note that deriving them did not require much creativity: the process we followed was systematic. This is the idea!


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *