Neither one is "stronger" in the mathematical sense:
- Path coverage does not imply condition coverage, as illustrated by an example in your question
- Condition coverage does not imply path coverage, as illustrated by your comment (condition
IF(A&&B)
with pairs A=TRUE, B=FALSE
and A=FALSE, B=TRUE
).
This means that claims that either side is somehow "stronger" would be invalid.
If you "upgrade" the condition coverage to modified condition/decision coverage, however, the answer would be "yes": MC/DC always implies covering the path, but covering the path may not necessarily imply even covering the condition, let alone MC/DC.
However, this does not imply that 100% MC/DC is always better than path coverage: the tradeoff is that it comes at much steeper "price" than a 100% path coverage due to the need to write more tests. Sometimes, a lot more. This has a potential of complicating the maintenance of your test suite.
I think it is a good idea to maintain a good balance between condition/decision coverage and path coverage by path-covering simple conditions (such as argument checks of the "null or empty" sort) and condition/decision-covering statements with complex business logic.
Based on your definitions, it looks like edge coverage does not imply condition coverage, but condition coverage does imply edge coverage. In other words, by covering all conditions, you will be guaranteed to cover every edge; but by covering every edge, you are not guaranteed to cover every condition.
For example,
int function(int arg1, int arg2)
{
if(arg1 < 0 || arg2 < 0)
return -1;
else
return arg1 + arg2;
}
Going by edge coverage, the edges here are "return -1", and "return arg1 + arg2"; in order to cover both of those edges, you need only two invocations:
function(-1, 0); function(0, 0);
There are, however, three conditions (considering the Boolean short-circuiting logic): arg1 < 0
, arg1 >= 0 && arg2 < 0
, and arg1 >= 0 && arg2 >= 0
, so you'd need something like the following to achieve complete condition coverage:
function(-1, 0); function(0, -1); function(0, 0);
The key distinction in the definitions you posted is "and all possible values of the constituents of compound boolean conditions are exercised at least once". Covering all the conditions will ensure that you will hit all the edges. But as you see, covering all the edges does not ensure that you will hit all the conditions.
Best Answer
The branch is an optionnal execution path, whereas a decision is the result of a combination of conditions (i.e. a boolean expression).
Thus, there can be decision without branch. For example:
In the above function, "(a > 5)" is a condition, "(b < 15)" is another condition. "(a > 5) && (b < 15)" is a decision. And there is no branch.
Thus in this example, the decision coverage will be reached with only 2 tests, and the branch coverage on source code reach 100% with a single test.
Branch coverage at assembly level would require the same two tests, but the question become tricky if you write the function like this:
There is still a boolean decision (computed with arithmetic operations) and the assembly would not have branches.
Nasa handbook on MCDC measurement clarify this type of differences. http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20040086014_2004090420.pdf