The question is how to (mechanically) select such test cases. Let’s continue using the same if
statement from the CountWords
program (from listing 3.4). The statement takes three booleans as input: (1) whether the current character is a letter and whether this letter is (2) “s” or (3) “r”. Generically, this is the same as the A
&&
(B
||
C)
example we just discussed.
To test this program, we first use a truth table to see all the combinations and their outcomes. In this case, we have three decisions, and 23 = 8. Therefore, we have tests T1 to T8, as listed in table 3.1.
Table 3.1 Truth table for the if
expression from the CountWords
program
Our goal is to apply the MC/DC criterion to these test cases and select N + 1 tests, which in this case means 3 + 1 = 4. To determine which four tests satisfy MC/DC, we need to go condition by condition, beginning by selecting the pairs of combinations (or tests) for the isLetter
part of the condition:
- For T1,
isLetter
,last
==
s
, andlast
==
r
are alltrue
, anddecision
(that is, the outcome of the entire boolean expression) is alsotrue
. We now look for another test in the table where the value ofisLetter
is the opposite of the value in T1 but the other values (last
==
s
andlast
==
r
) are the same. This means look for a test whereisLetter
isfalse
,last
==
s
istrue
,last
==
r
istrue
, anddecision
isfalse
. This combination appears in T5.Thus, we have found a pair of tests, T1 and T5 (an independence pair), whereisLetter
is the only parameter that is different and the outcome (decision
) changes. In other words, for this pair of tests,isLetter
independently influences the outcome (decision
). Let’s keep the pair{T1,
T5}
in our list of test cases. - We could stop here and move to the next variable. But finding all independence pairs for
isLetter
may help us reduce the final number of test cases, as you will see. So let’s continue and look at the next test. In T2,isLetter
istrue
,last
==
s
istrue
,last
==
r
isfalse
, anddecision
istrue
. We repeat the process and search for a test whereisLetter
is the opposite of the value in T2 butlast
==
s
andlast
==
r
remain the same. We find this combination in T6.We have found another pair of tests, T2 and T6, whereisLetter
is the only parameter that is different and the outcome (decision
) also changes, which we also add to our list of test cases. - We repeat the process for T3 (
isLetter
istrue
,last
==
s
isfalse
,last
==
r
istrue
) and find that theisLetter
parameter in T7 (isLetter
isfalse
,last
==
s
isfalse
,last
==
r
istrue
) is the opposite of the value in T3 and changes the outcome (decision
). - The pair for T4 (
isLetter
istrue
,last
==
s
isfalse
,last
==
r
isfalse
) is T8 (isLetter
isfalse
,last
==
s
isfalse
,last
==
r
isfalse
). The outcome of both tests is the same (decision
isfalse
), which means the pair{T4,
T8}
does not show howisLetter
can independently affect the overall outcome.
We do not find another new or suitable pair when repeating the process for T5, T6, T7, and T8, so we move on from the isLetter
parameter to the last
==
s
parameter. We repeat the same process, but now we search for the opposite value of parameter last
==
s
, while isLetter
and last
==
r
stay the same:
- For T1 (
isLetter
istrue
,last
==
s
istrue
,last
==
r
istrue
), we search for a test whereisLetter
istrue
,last
==
s
isfalse
,last
==
r
istrue
). This appears to be the case in T3. However, the outcome is the same for both test cases. Therefore,{T1,
T3}
does not show how thelast
==
s
parameter independently affects the outcome. - After repeating all the steps for the other tests, we find that only
{T2,
T4}
have different values for thelast
==
s
parameter where the outcome also changes.
Finally, we move to the last
==
r
parameter. As with the last
==
s
parameter, one pair of combinations works: {T3,
T4}
. I highly recommend carrying out the entire process yourself to get a feel for how it works.
We now have all the pairs for each parameter:
Having a single independence pair per variable (isLetter
, last
==
s
, and last
==
r
) is enough. We want to minimize the total number of tests, and we know we can achieve this with N + 1 tests. We do not have any choices with conditions last
==
s
and last
==
r
, as we found only one pair of tests for each parameter. This means we need tests T2, T3, and T4. Finally, we need to find the appropriate pair of tests for isLetter
. Note that any of the test pairs (T1-T5, T2-T6, or T3-T7) would work. However, we want to reduce the total number of tests in the test suite (and again, we know we only need four in this case).
If we were to pick T1 or T5, we would have to include the other as well, as they are opposites. Therefore, they are unnecessarily increasing the number of tests. To ensure that our test suite contains at most four test cases, we can add either T6 or T7, as their opposites (T2 and T3) are already included in our test cases. I picked T6 randomly. (You can have more than one set of tests that achieves 100% MC/DC, and all solutions are equally acceptable.)
Therefore, the tests we need for 100% MC/DC coverage are {T2,
T3,
T4,
T6}
. These are the only four tests we need—certainly cheaper than the eight tests we would need for path coverage. Now that we know which tests we need to implement, we can automate them.
Leave a Reply