Session 3.7 — Condition Coverage & MC/DC
Module 3: Dynamic Testing — White-box Techniques | Duration: 1 hour
Learning Objectives
- Define condition coverage and compute it for compound boolean expressions.
- Explain why condition coverage does not automatically satisfy branch coverage.
- Define Branch/Condition Coverage and Multiple Condition Coverage with their test count implications.
- Explain and apply Modified Condition/Decision Coverage (MC/DC) for safety-critical scenarios.
- Design minimum MC/DC test sets for compound decisions.
Concept Overview
Branch coverage ensures every decision goes both true and false, but it treats a compound condition like A AND B AND C as a single entity. Condition-level criteria break compound expressions into individual atomic conditions and require each to be independently exercised. This session covers the spectrum from basic Condition Coverage to the industry-standard MC/DC used in avionics, automotive, and medical software.
Each atomic condition in each decision is evaluated to both true and false at least once, regardless of the overall decision outcome.
All 2n combinations of n atomic conditions in each decision are tested. Thorough but exponentially expensive.
Each condition independently affects the decision outcome. Achieves near-MCC thoroughness with a linear (n+1) minimum test count. Required by DO-178C Level A.
Condition Coverage (CC)
Condition coverage requires that each atomic condition within every decision is evaluated to both true and false by at least one test case. An atomic condition is an indivisible boolean sub-expression that cannot be broken down further.
- Atomic condition: A single boolean predicate such as
age > 18,isPremium, orbalance ≥ amount. A compound condition likeage > 18 AND isPremiumcontains two atomic conditions. - Decision: The overall boolean expression controlling a branch (the full
ifcondition). - CC formula: CC% = (Condition outcomes covered ÷ Total condition outcomes) × 100. For n atomic conditions, total outcomes = 2n (each can be T or F).
| Decision (in code) | Atomic Conditions | Outcomes to cover |
|---|---|---|
if age >= 18 and has_id | C1: age ≥ 18, C2: has_id | C1=T, C1=F, C2=T, C2=F (4 outcomes) |
if x > 0 or y < 100 | C1: x > 0, C2: y < 100 | C1=T, C1=F, C2=T, C2=F (4 outcomes) |
if a and b and c | C1: a, C2: b, C3: c | 6 outcomes (T and F for each of C1, C2, C3) |
Condition Coverage — Worked Example
Consider the following access control function:
Decision D1 has three atomic conditions:
- C1:
role == "admin" - C2:
active - C3:
verified
| Test | role | active | verified | C1 | C2 | C3 | D1 outcome |
|---|---|---|---|---|---|---|---|
| TC-1 | "admin" | True | True | T | T | T | True (Access Granted) |
| TC-2 | "user" | False | False | F | F | F | False (Access Denied) |
Each of C1, C2, C3 has been both True (TC-1) and False (TC-2). CC = 6/6 = 100%. Branch coverage is also satisfied: D1 is True (TC-1) and False (TC-2). But this 2-test set is minimal only because all conditions flip together.
Limitation of Condition Coverage
Consider: if A or B with tests:
| Test | A | B | Decision (A OR B) |
|---|---|---|---|
| TC-1 | True | False | True |
| TC-2 | False | True | True |
CC = 100% (A is T and F; B is T and F). But the decision outcome is always True. The false branch of the if is never taken. This means 100% CC does NOT imply 100% branch coverage.
Condition coverage alone is insufficient. You must combine it with branch coverage (Branch/Condition Coverage) or use MC/DC to properly handle compound decisions. This is why safety standards do not accept CC alone.
Branch/Condition Coverage (B/CC)
Branch/Condition Coverage requires that both Branch Coverage AND Condition Coverage are satisfied simultaneously. Every decision must evaluate to both T and F, AND every atomic condition must evaluate to both T and F.
- Every branch outcome (T and F) of every decision is exercised — this satisfies BC.
- Every atomic condition appears as both true and false across the test set — this satisfies CC.
- Both must be satisfied by the same test suite (not separately).
For 100% B/CC we need: D1 = True at least once, D1 = False at least once, each of C1,C2,C3 = T at least once, each = F at least once.
| Test | C1 (role=admin) | C2 (active) | C3 (verified) | D1 |
|---|---|---|---|---|
| TC-1 | T | T | T | T → Access Granted |
| TC-2 | F | F | F | F → Access Denied |
TC-1 and TC-2 together achieve B/CC = 100%. However, this does NOT show whether each condition independently matters — that is what MC/DC adds.
Multiple Condition Coverage (MCC)
Multiple Condition Coverage (also called compound condition coverage) requires that all possible combinations of truth values for all atomic conditions in each decision are exercised. For n atomic conditions, this means 2n combinations.
| Test | C1 | C2 | C3 | D1 = C1 AND C2 AND C3 |
|---|---|---|---|---|
| TC-1 | T | T | T | T |
| TC-2 | T | T | F | F |
| TC-3 | T | F | T | F |
| TC-4 | T | F | F | F |
| TC-5 | F | T | T | F |
| TC-6 | F | T | F | F |
| TC-7 | F | F | T | F |
| TC-8 | F | F | F | F |
MCC requires all 8 tests (23). For 4 conditions: 16 tests. For 10 conditions: 1024 tests. This exponential growth makes MCC impractical for complex decisions.
100% MCC automatically implies 100% CC, 100% BC, and 100% B/CC. It is the most thorough condition-level criterion but rarely applied due to cost.
Modified Condition/Decision Coverage (MC/DC)
MC/DC is the practical middle ground between B/CC and MCC. It requires that each atomic condition in a decision independently influences the decision outcome — while keeping other conditions fixed.
- Every decision in the program has been exercised to a true outcome and a false outcome (satisfies Branch Coverage).
- Every atomic condition in the program has been exercised to a true outcome and a false outcome (satisfies Condition Coverage).
- Every atomic condition has been shown to independently affect the decision outcome — by finding a pair of tests where only that condition differs and the decision outcome changes.
An independence pair for condition Ci is a pair of test cases (TCx, TCy) such that:
- Ci changes value between TCx and TCy (T in one, F in the other).
- All other conditions (Cj where j ≠ i) have the same values in both TCx and TCy.
- The decision outcome is different in TCx and TCy.
For n atomic conditions, MCC needs 2n tests. MC/DC needs only n + 1 tests minimum. For 10 conditions: MCC = 1024 tests, MC/DC = 11 tests. This efficiency makes MC/DC the standard for safety-critical software (DO-178C for aviation, ISO 26262 for automotive, IEC 62304 for medical).
MC/DC Worked Example
We use the same grant_access decision: D1 = C1 AND C2 AND C3
| Test | C1 | C2 | C3 | D1 |
|---|---|---|---|---|
| TC-1 | T | T | T | T |
| TC-2 | T | T | F | F |
| TC-3 | T | F | T | F |
| TC-4 | T | F | F | F |
| TC-5 | F | T | T | F |
| TC-6 | F | T | F | F |
| TC-7 | F | F | T | F |
| TC-8 | F | F | F | F |
| Condition | Independence Pair | Justification |
|---|---|---|
| C1 | TC-1 (T,T,T → T) vs TC-5 (F,T,T → F) | C1 changes (T→F), C2=T and C3=T in both. D1 changes (T→F). C1 independently affects D1. |
| C2 | TC-1 (T,T,T → T) vs TC-3 (T,F,T → F) | C2 changes (T→F), C1=T and C3=T in both. D1 changes (T→F). C2 independently affects D1. |
| C3 | TC-1 (T,T,T → T) vs TC-2 (T,T,F → F) | C3 changes (T→F), C1=T and C2=T in both. D1 changes (T→F). C3 independently affects D1. |
Select the union of all tests appearing in the independence pairs:
MC/DC Test Set = {TC-1, TC-2, TC-3, TC-5} — just 4 tests (n+1 = 3+1 = 4) instead of 8 for MCC.
| Test | role | active | verified | Expected | Covers |
|---|---|---|---|---|---|
| TC-1 | "admin" | True | True | Access Granted | Base case (all T) + D1=True branch |
| TC-2 | "admin" | True | False | Access Denied | C3 independence pair |
| TC-3 | "admin" | False | True | Access Denied | C2 independence pair |
| TC-5 | "user" | True | True | Access Denied | C1 independence pair |
- Branch Coverage: D1=True (TC-1), D1=False (TC-2, TC-3, TC-5) — both outcomes covered. ✓
- Condition Coverage: C1=T(TC-1,2,3), C1=F(TC-5); C2=T(TC-1,2,5), C2=F(TC-3); C3=T(TC-1,3,5), C3=F(TC-2) — all T and F covered. ✓
- Independence: Each condition has a pair showing it alone changes the decision. ✓
Coverage Criteria Comparison
| Criterion | What is required | Min tests (n=3 conditions) | Subsumes | Standard |
|---|---|---|---|---|
| Statement Coverage (SC) | Every statement executed | 1 | — | Basic CI gate |
| Branch Coverage (BC) | Every branch T and F taken | 2 | SC | Unit test standard |
| Condition Coverage (CC) | Each atomic condition T and F | 2 | — (not BC) | Supplementary |
| B/CC | BC + CC simultaneously | 2–3 | SC, BC, CC | Good practice |
| MC/DC | Each condition independently affects decision | n+1 = 4 | SC, BC, CC | DO-178C, ISO 26262 |
| MCC | All 2n combinations | 23 = 8 | All above | Rarely practical |
Level A (catastrophic failure): MC/DC required. Level B (hazardous): Decision coverage required. Level C: Statement coverage required.
ASIL D (highest): MC/DC required. ASIL B/C: Branch coverage required. ASIL A: Statement coverage.
Class C (life-sustaining): MC/DC recommended. Class B: Branch coverage. Class A: Statement coverage.
Common Mistakes
As shown: 100% CC does not guarantee branch coverage when compound conditions allow the overall decision to stay true/false across all tests.
Changing two conditions between a pair invalidates the independence requirement. Only one condition may change per pair while others are held constant.
Languages with short-circuit AND/OR may not evaluate all conditions. MC/DC test cases must be designed so all conditions are actually evaluated.
MCC tests all 2n combinations. MC/DC only needs n+1 carefully chosen tests. They are not the same; MC/DC is far more efficient.
Class Activity
Consider the following decision in a loan eligibility checker:
Let: C1 = credit_score ≥ 700, C2 = annual_income > 300000, C3 = not has_default
- Build the full MCC truth table (8 rows) and label each with the decision outcome.
- Find independence pairs for C1, C2, and C3 from the truth table.
- Select the minimum MC/DC test set (should be 4 tests).
- Write concrete test inputs (actual credit_score, income, has_default values) for each selected test.
- Verify that your MC/DC set achieves 100% BC and 100% CC for this decision.
- 2 marks: Correct and complete MCC truth table (8 rows, correct outcomes).
- 3 marks: Correct independence pairs for all three conditions with justification.
- 2 marks: Correct minimum MC/DC test set selection (TC-1, TC-2, TC-3, TC-5 or equivalent).
- 2 marks: Concrete and valid test inputs mapped to each MC/DC test.
- 1 mark: Correct verification that BC and CC are satisfied by the MC/DC set.
Exit Ticket
- Explain in one sentence why 100% Condition Coverage does not guarantee 100% Branch Coverage. Give a counter-example with a 2-condition OR decision.
- A decision has 5 atomic conditions. How many tests does MCC require? How many does MC/DC require?
- What makes a valid independence pair for MC/DC? Name three requirements an independence pair must satisfy.
Summary & Assignment
Condition coverage breaks compound boolean expressions into atomic parts and requires each to be exercised both ways. However, CC does not subsume branch coverage. Branch/Condition Coverage satisfies both simultaneously. Multiple Condition Coverage tests all 2n combinations but is exponentially expensive. MC/DC achieves near-MCC thoroughness with only n+1 tests by requiring each condition to independently affect the decision — making it the standard for safety-critical software certification.