Engineering Method

Coverage, as a game

Every if multiplies the ways code can behave. So how many tests do youactually need? Everything below is built from one thing: a unit, a single branch of a decision. It is a row in a table, a test in the suite, and a pip on this page, all the same object. It wears one of four states, everywhere.

  • WonVerified at its level. Counts toward 1.
  • OpenOwed a test. Holds the score below 1.
  • EscalatedLives above unit: architecture we do not own.
  • ParkedUnreachable today. Kept, never deleted.

1 · The explosion

3 conditions
Path coverage2ᵏ
0

Every combination. Explodes.

Branches × 22k
0

The tempting shortcut. Wrong past k=2.

MC/DCk + 1
0

What you actually write. Stays calm.

At k = 1 and k = 2 all three agree, which is exactly why the shortcut looks correct. Push past 2 and watch path coverage detonate while MC/DC barely moves.

2 · Find the tests

Required tests found: 0 / 3

if ( && )
    // then: happy path
else
    // else: sad path

Toggle c1 and c2 to visit every reachable row.

c1c2OutcomeRole
TTthenHappy path
FTelseFlip c1
TFelseFlip c2
FFelseRedundant

3 · Nothing is lost

A branch a unit test cannot reach does not disappear. It bubbles up to the level thatcan verify it, and stays documented there.

ManualLast resort. A documented human step. Still tracked.
SmokeObserved against the live deployment.
E2EThrough the running app, when a unit cannot isolate it.
UnitFast, isolated, preferred. Most branches live here.

The decisions behind it

  1. Which criterion?MC/DC, not branches×2 (breaks at 3 conditions) and not 2ᵏ path coverage (explodes).
  2. Prune unreachable rows?No. Every branch is a permanent row. A future change can make it live.
  3. A branch a unit cannot reach?It bubbles up the pyramid (E2E → smoke → manual). It is never lost.
  4. "Cannot be tested"?A finding, not an exemption: fix the missing seam, or document why we do not own it.