So, assuming that you've run all of your tests and you've achieved 100% MC/DC. Does that mean that the compiler has correctly compiled your code?
In short, the answer is no.
Let's see an example to illustrate a case where 100% MC/DC fails to expose a compiler fault.
Imagine that some optimization rule is wrong in your version of the compiler and functions that start with an or operation accidentally get xor operations instead. Can you still achieve 100% MC/DC for software generated with this compiler without exposing the fault? It turns out that you can!
As an example, assume that the expression you are testing is (written in Ada):
x := y or z;
In C the same expression could be written as:
x = (y!=0) | (z!=0);
Note that we've used a bitwise or in this case, as the logical or (||) has slightly different behavior, namely the second expression isn't evaluated if the first expression is true, which is different to the Ada code's behavior.
We can achieve 100% MC/DC for the above code with the following test cases:
- Input:
y = True, z = False
; Output:x = True
- Input:
y = False, z = True
; Output:x = True
- Input:
y = False, z = False
; Output:x = False
In this situation, Testcase 1 and Testcase 3 together achieve the MC/DC of condition y
, and Testcase 2 and Testcase 3 achieve MC/DC of condition z
.
If the compiler generates code where x
is defined as y xor z
, executing the test cases defined above would give you exactly the results you expect. However, if you happened to rerun the tests with both y
and z
as True
(not required for MC/DC), the behavior of the code would be incorrect (you would expect a True
result and would actually get a False
result). Clearly, MC/DC is not a good way to argue that object code is correctly generated.