Why is full path coverage impractical, and what criteria are used instead?
answer
- Count the routes, not the lines
- Sequential decisions multiply the count
- Loops make the count unbounded
- Some counted routes cannot be taken at all
- Each condition must flip the outcome alone
basics
~20 sPath coverage requires exercising every route through a function, and routes multiply exponentially with sequential decisions and become unbounded once loops are involved. Suites use weaker criteria instead: decision coverage, or modified condition/decision coverage where each condition must independently flip the outcome.
solid answer
~50 sA path is one complete route through a function's control-flow graph. Nine independent sequential decisions already give 512 routes, and any loop whose trip count depends on data makes the set unbounded, so full path coverage is unreachable for ordinary code. Many counted routes are also infeasible — no input can take them — so the denominator itself is not knowable. Practice therefore climbs a subsumption ladder and stops early: statement, then decision, then condition-plus-decision, then modified condition/decision coverage (MC-DC), then multiple-condition, then path. MC-DC is the usual stopping point where rigour is mandated, because it requires each condition to independently change the decision's outcome and needs on the order of n+1 cases for n conditions instead of 2^n. Loops are handled by deliberate cases — zero, one, many, and the boundary — rather than by counting routes.
code
pseudocode · 4 linesfunction isEligible(subject):
return subject.ageYears >= 18
and subject.consentSignedOn != null
and not subject.onExcludedMedicationgo deeper
You are not expected to design these criteria, but know that a path means one whole route through a function and that the number of routes explodes with decisions and loops. Recognising the words statement, decision and path in order is enough.
Explain the subsumption order and the combinatorics: 2^n routes for n sequential decisions, unbounded with data-dependent loops, and the trap that condition coverage alone does not give decision coverage.
Show where a real project stops and why: decision coverage plus deliberately designed cases, with the stricter criteria reserved for regulated code. Be able to talk about infeasible routes and loop boundary cases without reaching for a percentage.
Own the decision about which criterion an organisation requires and where. Rigour has a cost in case-set maintenance and run time, the evidence for the stricter criteria outside regulated domains is thin, and mandating one everywhere buys less than targeting it at the risky components.
## What a path is, and why counting them fails A **path** is one complete route through a function's control-flow graph, from entry to exit, recording the direction taken at every decision along the way. Path coverage asks for every such route to be exercised. It is the strongest structural criterion in ordinary use, and it is essentially never achieved. The arithmetic is unforgiving. Independent sequential decisions multiply: two give 4 routes, nine give 512, twenty give over a million. A clinical-trial data-capture form with nine independent field-level guards, none of them nested, is not an exotic piece of code, and it already has 512 routes through a function most reviewers would call simple. Add a loop whose trip count depends on the data — iterating over however many visit records a subject has — and the route count is no longer finite at all, because each distinct number of iterations is a distinct path. There is a second, subtler problem: **infeasibility**. The graph counts routes that no input can produce, because earlier decisions constrain later ones. If a record cannot be both "unconsented" and "already randomised", the routes combining those outcomes are unreachable. So the denominator of a path-coverage percentage is not merely large, it is not reliably knowable, and a number computed against it would be meaningless even if you could run the cases. ## The subsumption ladder Structural criteria form a partial order, each stronger criterion implying the weaker ones beneath it: 1. **Statement coverage** — every executable statement runs. 2. **Decision (branch) coverage** — every decision takes every outcome. 3. **Condition coverage** — every atomic condition inside a decision takes both values. On its own this does *not* imply decision coverage, which surprises people. 4. **Condition/decision coverage** — both of the above together. 5. **MC-DC** — modified condition/decision coverage, below. 6. **Multiple-condition coverage** — every combination of conditions inside each decision: 2^n cases for n conditions. 7. **Path coverage** — every route through the graph. The condition-versus-decision trap is worth internalising. For the decision `a AND b`, the two cases (true, false) and (false, true) give each condition both values — full condition coverage — while the decision evaluates false both times. Decision coverage sits at 50% with condition coverage at 100%. ## MC-DC: the practical top of the ladder Modified condition/decision coverage requires that every condition in a decision be shown to **independently affect the decision's outcome**. For each condition you need a pair of cases in which that condition differs, the outcome differs, and the other conditions are held such that they are not responsible for the change. Its appeal is cost. Multiple-condition coverage needs 2^n cases for n conditions; MC-DC is commonly cited as needing a minimum of n+1 and at most about 2n. For an eligibility predicate with six conditions that is roughly seven cases instead of sixty-four — the difference between a case set a team can maintain across a 3-week release train and one nobody will ever write. MC-DC is required by certification regimes for the most critical categories of safety-related software; outside those regimes it is uncommon, and the independent empirical evidence about how much better it detects defects than plain decision coverage is limited and contested, so present it as a rigour requirement rather than a proven win. One complication worth naming: **short-circuiting**. When a language stops evaluating a boolean expression as soon as the outcome is settled, some condition values are never actually computed, which changes which case pairs are achievable and is a standard source of arguments about what a given MC-DC number means. ## Loops, and what teams do instead Since loops make path counts unbounded, loop testing uses heuristics rather than enumeration: exercise the loop zero times, once, and many times, plus the boundary cases at the minimum and maximum trip counts and, where a maximum exists, one past it. This is a deliberate case-design technique, not something a coverage percentage will hand you — branch coverage sees only "body entered" and "loop exited" and reports both green after a single well-chosen input. A related idea is choosing a **basis set** of linearly independent paths: rather than all routes, exercise a set from which every other route can be composed. The size of such a set is bounded by the number of independent decisions in the function, which keeps it finite, though selecting and maintaining one by hand is laborious enough that it stays a specialist technique. ## How to answer this in an interview State the combinatorics first, then infeasibility, then the ladder, then where real projects stop. Most teams stop at decision coverage and spend their remaining effort on choosing better cases rather than climbing higher; regulated work climbs to MC-DC because a standard says so. Claiming a team should aim for path coverage is the answer that marks a candidate as having never counted the routes in a real function.
- Why does full condition coverage not imply full decision coverage?Because condition coverage constrains the atomic terms, not the result. For `a AND b`, the cases (true, false) and (false, true) give both conditions both values, yet the decision is false in both, so one of its two outcomes was never taken. Condition/decision coverage exists precisely to close that hole by demanding both at once.
- Roughly how many cases does MC-DC need for a decision with n conditions?The commonly cited figures are a minimum of n+1 and an upper bound near 2n, against 2^n for multiple-condition coverage. That linear-rather-than-exponential growth is the whole reason MC-DC exists: it keeps a rigorous criterion affordable on decisions with five or six conditions, where enumerating every combination would not be.
- If path counts are unbounded for loops, how do you decide which loop cases to write?By deliberate design rather than enumeration: run the loop zero times, once, and many times, and add the boundary trip counts — the minimum, the maximum, and one beyond the maximum where a maximum exists. Nested loops are usually exercised innermost-first with the outer loops held at minimum counts, because the full cross-product is unaffordable.
saying these in an interview costs you the question
- Thinks full branch coverage means every path was exercised
- Assumes every route counted in the graph is reachable
- Says condition coverage always implies decision coverage
- Treats MC-DC as requiring all condition combinations
- Believes loops add only a fixed number of paths
- Recommends path coverage as a realistic team target