White Box · Structural

Condition Coverage

Condition coverage requires that each individual boolean sub-expression within a compound decision is evaluated as both true and false at least once. It is stronger than branch coverage for compound conditions — and the foundation of MC/DC, the coverage standard for safety-critical software.

Senior Test Lead ISTQB CTFL 4.3.3 · CTAL-TA 4.3

What it is

In most real code, decision points are not simple single conditions — they are compound expressions. if (age >= 18 && hasLicence) contains two atomic conditions: age >= 18 and hasLicence. Branch coverage only cares whether the overall decision evaluates to true or false. Condition coverage goes further: it requires each atomic condition to independently take both a true and a false value across the test suite.

This distinction matters because a compound condition can reach both overall outcomes (true/false) without every atomic condition being exercised on both sides. A bug in one condition might be masked by the other condition always dominating the result.

Atomic condition: a sub-expression within a compound boolean decision that cannot be decomposed further without breaking the boolean nature of the expression. In (A && B) || C, the atomic conditions are A, B, and C. The expressions (A && B) and (A && B) || C are not atomic — they are compound.

Condition coverage vs. branch coverage

Consider this decision: if (A && B)

Branch coverage requires:

  • One test where the overall decision is true: A=true, B=true → overall true
  • One test where the overall decision is false: A=false, B=anything → overall false

With these two tests, B has only ever been evaluated as true (in the first test where B=true) and as “don’t care” (short-circuit evaluation means B may not even be evaluated in the second test). A bug in the B=false branch of the implementation is never triggered.

Condition coverage additionally requires:

  • A evaluated as true at least once
  • A evaluated as false at least once
  • B evaluated as true at least once
  • B evaluated as false at least once

This forces at least one test where B=false is actually evaluated, catching the bug that branch coverage misses.

Important: condition coverage does not subsume branch coverage. It is possible to achieve 100% condition coverage while not covering both branches of a decision. In practice, teams require condition/decision coverage (both criteria combined) or the even stronger MC/DC.

Modified Condition/Decision Coverage (MC/DC)

MC/DC is the gold standard for safety-critical systems (avionics standard DO-178C, automotive AUTOSAR, medical device IEC 62304). It extends condition coverage with one additional requirement: each condition must independently affect the outcome of the decision.

For each atomic condition C, there must be a pair of test cases that differ only in the value of C, while all other conditions remain constant, and the overall decision outcome changes. This proves that C is not redundant and that a fault in C would be observable in the decision output.

MC/DC for a decision with N conditions requires at minimum N+1 test cases (compared to 2² for full combinatorial coverage). For a decision with 5 conditions, MC/DC needs at least 6 test cases, not 32.

Worked example: insurance eligibility

A function determines insurance eligibility with the condition:

if (age >= 18 && hasLicence && noClaims) {
  eligible = true;
} else {
  eligible = false;
}

Three atomic conditions: A = age ≥ 18, B = hasLicence, C = noClaims.

Branch coverage minimum: 2 tests (overall true, overall false). Condition coverage minimum: 3 pairs of tests, one for each condition evaluated both ways.

Insurance eligibility — condition coverage test cases
TC A: age ≥ 18 B: hasLicence C: noClaims Eligible Conditions exercised
TC1T (age=25)TTtrue A=T, B=T, C=T
TC2F (age=16)TTfalse A=F — covers A both ways with TC1
TC3T (age=25)FTfalse B=F — covers B both ways with TC1
TC4T (age=25)TFfalse C=F — covers C both ways with TC1
MC/DC pairs — each condition independently determines outcome
Condition under test Test case 1 Test case 2 A B C Result changes?
A independently affects outcome TC1TC2 T→FT (same)T (same) Yes (true→false)
B independently affects outcome TC1TC3 T (same)T→FT (same) Yes (true→false)
C independently affects outcome TC1TC4 T (same)T (same)T→F Yes (true→false)

TC1 through TC4 achieve both condition coverage and MC/DC for this three-condition decision. Four test cases cover what branch coverage would achieve with two tests — but each of TC2, TC3, and TC4 targets a specific condition in isolation that branch coverage leaves unverified.

Deriving condition coverage test cases systematically

  1. Identify atomic conditions — decompose every compound boolean decision in the code into its atomic sub-expressions. Each sub-expression that cannot be split further is one condition to cover.
  2. For each condition, find a baseline — a test case where all other conditions are true (for AND logic) so the condition under test independently determines the outcome. This is your MC/DC anchor test.
  3. Create a partner — copy the baseline test and flip only the condition under test. Verify the overall decision outcome flips. This is the MC/DC pair.
  4. Verify coverage — check that every atomic condition appears as true in at least one test and false in at least one test across the complete test suite.
  5. Add branch coverage check — confirm the overall decision is true in at least one test and false in at least one test. Combined condition/decision coverage is now achieved.

ISTQB mapping

ISTQB reference
Syllabus refTopicLevel
CTFL 4.3.3Condition coverage — basic definition and distinction from branch coverageFoundation
CTAL-TA 4.3Condition coverage, condition/decision coverage, and MC/DC — full applicationAdvanced / Senior
CTAL-TA 4.3 K4Analyse code to determine test cases achieving condition coverage and MC/DCAdvanced LO

Foundation candidates need to know that condition coverage exists and how it differs from branch coverage. Advanced (CTAL-TA) candidates must be able to derive test cases that achieve MC/DC for a given compound decision — this is a K4 (analyse) objective.

Common mistakes

  • Confusing condition coverage with branch coverage — they are not equivalent. Branch coverage checks the overall decision outcome; condition coverage checks each atomic sub-expression. A test suite can achieve 100% branch coverage while leaving conditions untested in one direction.
  • Forgetting short-circuit evaluation — in most languages, A && B does not evaluate B if A is false. A test where A=false may not exercise B at all. Design tests specifically to ensure B is evaluated (set A=true) when testing B.
  • Not testing each condition independently — basic condition coverage only requires each condition to be true and false somewhere. MC/DC additionally requires independence. Write the independence argument explicitly for safety-critical work.
  • Applying condition coverage to trivial single-condition decisions — if a decision has only one atomic condition (e.g., if (isLoggedIn)), condition coverage is identical to branch coverage. Only invest in the distinction when decisions are compound.
  • Assuming 100% condition coverage means no bugs — condition coverage verifies that each condition is exercised both ways. It does not verify that the logical operator between conditions is correct. A developer who wrote || instead of && may not be caught by condition coverage alone.

Condition coverage sits above Branch Coverage in strength: branch coverage is a prerequisite, and condition coverage adds the per-atomic-condition requirement on top.

For the complete white-box coverage hierarchy: Statement Coverage ⊂ Branch Coverage ⊂ Condition Coverage ⊂ MC/DC ⊂ Path Coverage. Each level subsumes the one below it, but adds test cases that the lower level misses.

The conditions you are testing with condition coverage often correspond directly to the rows of a Decision Table. Combining both approaches — decision tables to enumerate the specification logic, condition coverage to verify the implementation — gives strong coverage from both ends.

Practice this technique: Try Test Lead Practice 07 — Test coverage gaps.