Skip to content

MC/DC vs condition coverage vs multiple condition coverage

Condition coverage takes each condition through both values. Multiple condition coverage takes every combination. MC/DC sits between: each condition shown to affect the outcome on its own, in about n + 1 tests. The machine interlock below has four conditions, so the three criteria cost four, sixteen and five tests.

The rule is start AND guard_closed AND NOT (estop OR fault): the machine runs when start is pressed, the guard is closed, and neither the emergency stop nor a fault is active. Sixteen rows. Condition coverage is met by two tests, all-TRUE and all-FALSE, which take every condition through both values and tell you nothing about any of them individually. Multiple condition coverage is all sixteen rows. MC/DC needs the engine's four independence pairs, which share scenarios and come to five distinct rows.

The pairs are: start, from the running scenario with start released (stops) to start pressed (runs); guard_closed, from guard open (stops) to closed (runs); estop, from running to estop active (stops); fault, from running to fault active (stops). Four pairs, five scenarios, and each scenario has an expected result that follows from the safety requirement rather than from the formula.

Decision coverage, also called branch coverage, is weaker still: the outcome in both values, which two tests achieve without regard to conditions. The comparison on the condition-versus-decision page uses a smaller rule to show the gap. For safety logic the point of MC/DC is the one the interlock makes obvious: a stuck estop that never affected the outcome would pass condition coverage and fail its independence pair.

Example

run := start AND guard_closed AND NOT (estop OR fault) · output

Exact checks

Always true (tautology)? No Counterexample: start = F, guard_closed = F, estop = F, fault = F · Exhaustively checked and solver cross-checked · 1 rows
Always false (contradiction)? No Counterexample: start = T, guard_closed = T, estop = F, fault = F · Exhaustively checked and solver cross-checked · 13 rows
Can be true? Yes Example assignment: start = T, guard_closed = T, estop = F, fault = F · Exhaustively checked and solver cross-checked · 13 rows

Truth table (16 rows)

MC/DC vs condition coverage vs multiple condition coverage
#startguard_closedestopfaultrun
0FALSEFALSEFALSEFALSEFALSE
1FALSEFALSEFALSETRUEFALSE
2FALSEFALSETRUEFALSEFALSE
3FALSEFALSETRUETRUEFALSE
4FALSETRUEFALSEFALSEFALSE
5FALSETRUEFALSETRUEFALSE
6FALSETRUETRUEFALSEFALSE
7FALSETRUETRUETRUEFALSE
8TRUEFALSEFALSEFALSEFALSE
9TRUEFALSEFALSETRUEFALSE
10TRUEFALSETRUEFALSEFALSE
11TRUEFALSETRUETRUEFALSE
12TRUETRUEFALSEFALSETRUE
13TRUETRUEFALSETRUEFALSE
14TRUETRUETRUEFALSEFALSE
15TRUETRUETRUETRUEFALSE

Plain-language reading

Beginnerrun is true exactly when all of the following hold:
1. start is true
2. guard_closed is true
3. the following condition does not hold:
3.1. at least one of estop or fault is true (both may be true)
In every other case, run is false.
About the operators:
- AND is true only when all of its parts are true.
- NOT reverses a value: true becomes false and false becomes true.
- OR is inclusive: it is true when at least one part is true, including when several are.
Intermediaterun is true exactly when all of the following hold:
1. start is true
2. guard_closed is true
3. the following condition does not hold:
3.1. at least one of estop or fault is true (both may be true)
In every other case, run is false.
Advancedrun is true exactly when all of the following hold [conjunction ∧]:
1. start is true
2. guard_closed is true
3. the following condition does not hold [negation ¬]:
3.1. at least one of estop or fault is true (both may be true) [inclusive disjunction ∨]
In every other case, run is false.
Formal notation: start ∧ guard_closed ∧ ¬(estop ∨ fault)

Logic diagram

MC/DC vs condition coverage vs multiple condition coverage MC/DC vs condition coverage vs multiple condition coverage start guard_closed estop fault run AND NOT OR
MC/DC vs condition coverage vs multiple condition coverage MC/DC vs condition coverage vs multiple condition coverage start guard_closed estop fault run AND NOT OR

MC/DC

InputStatusIndependence pair (only that input changes)
startfoundstart=F, guard_closed=T, estop=F, fault=F → F  |  start=T, guard_closed=T, estop=F, fault=F → T
guard_closedfoundstart=T, guard_closed=F, estop=F, fault=F → F  |  start=T, guard_closed=T, estop=F, fault=F → T
estopfoundstart=T, guard_closed=T, estop=F, fault=F → T  |  start=T, guard_closed=T, estop=T, fault=F → F
faultfoundstart=T, guard_closed=T, estop=F, fault=F → T  |  start=T, guard_closed=T, estop=F, fault=T → F

The common slip

Reporting condition coverage as if it showed each condition's effect. Two tests, all-TRUE and all-FALSE, give one hundred percent condition coverage of the interlock and never demonstrate that the emergency stop does anything.

Questions

Why is MC/DC n + 1 and not 2n?

Because pairs share scenarios: the running scenario serves as one half of every pair here. In the worst case 2n tests are needed; for most rules the shared base rows bring it down to n + 1.

Does MC/DC guarantee the rule is right?

No. It guarantees that the suite shows each condition's influence on the rule as written. The expected results still have to come from the requirement, which is the pitfall page's point about coverage and correctness.

Related

Practice

See also

Testing and rules

Generated from the Tangibool engine, semantics tangibool-semantics/1, engine 1.0.0, build . Every table, map, simplification and verdict on these pages was computed by the Tangibool engine when the site was built, and every claim was re-checked by the same exact checker the app uses. Limits are stated where they apply. © 2026 Foreranger LTD.