You may have noticed that some of the criteria we have discussed are more rigorous than others. For example, a single test is enough to achieve 100% line coverage, but two tests are needed for 100% branch coverage. Some strategies subsume other strategies. Formally, a strategy X subsumes strategy Y if all elements that Y exercises are also exercised by X. Figure 3.7 illustrates the relationships among the coverage criteria.
Figure 3.7 The different coverage criteria and their subsumption relations
Branch coverage subsumes line coverage, which means 100% branch coverage always implies 100% line coverage. However, 100% line coverage does not imply 100% branch coverage. Moreover, 100% condition + branch coverage always implies 100% branch coverage and 100% line coverage. Following this train of thought, we see that path coverage subsumes all other criteria. This is logical as path coverage covers all possible paths of the program. Next, we see that MC/DC is stronger than condition + branch coverage, as MC/DC ensures the independence of each condition. And condition + branch coverage subsumes both branch and condition coverage independently. Finally, all other criteria, except basic condition coverage, subsume line coverage, which is the weakest criterion in the figure.
You now understand the trade-offs of choosing one criterion over another. A weaker criterion may be cheaper and faster to achieve but leave many parts of the code uncovered. On the other hand, a stronger criterion may cover the code more rigorously at a higher cost. It is up to you, the developer, to decide which criterion to use.
NOTE Basic condition coverage does not necessarily subsume line coverage, for the same reason we always use condition + branch coverage together. We can achieve 100% basic condition coverage in a simple if(A
||
B)
by having two tests, T1={true, false} and T2={false, true}. But both tests make the decision block true
, so the false
branch and its lines are not exercised.
Leave a Reply