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 string, empty string, string 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 (str, open, close) category with five partitions (string does not contain either the open or close tags, 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). This means you would start with the str null partition and combine it with the partitions of the open, close, and (str, open, close) 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
openandclose, and one where it does not. - Unless we have a good reason to believe that the program handles
openandclosetags of different lengths in different ways, we do not need the four combinations of (open length = 1, close length = 1), (open length > 1, close length = 1), (open length = 1, close length > 1), and (open length > 1, close length > 1). Just (open length = 1, close length = 1) and (open length > 1, close 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 > 1open—Null string [x], empty string [x], length = 1, length > 1close—Null string [x], empty string [x], length = 1, length > 1str—Null string [x], empty string [x], length = 1, length > 1- (
str,open,close)—String does not contain either theopenor theclosetag, string contains theopentag but does not contain theclosetag, string contains theclosetag but does not contain theopentag, string contains both theopenandclosetags, string contains both theopenandclosetags 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:
stris null. - T2:
stris empty. - T3:
openis null. - T4:
openis empty. - T5:
closeis null. - T6:
closeis empty.
- T7: The single character in
strmatches theopentag. - T8: The single character in
strmatches theclosetag. - T9: The single character in
strdoes not match either theopenor theclosetag. - T10: The single character in
strmatches both theopenandclosetags.
Now, str length > 1, open length = 1, close = 1 :
- T11:
strdoes not contain either theopenor theclosetag. - T12:
strcontains theopentag but does not contain theclosetag. - T13:
strcontains theclosetag but does not contain theopentag. - T14:
strcontains both theopenandclosetags. - T15:
strcontains both theopenandclosetags multiple times.
Next, str length > 1, open length > 1, close > 1 :
- T16:
strdoes not contain either theopenor theclosetag. - T17:
strcontains theopentag but does not contain theclosetag. - T18:
strcontains theclosetag but does not contain theopentag. - T19:
strcontains both theopenandclosetags. - T20:
strcontains both theopenandclosetags multiple times.
Finally, here is the test for the boundary:
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!
Leave a Reply