White Box · Structure-Based

Statement Coverage

Execute every executable statement in the code at least once. It’s the most basic white box metric — a necessary starting point, not a sufficient end point.

Senior ISTQB CTFL v4.0 — 4.3.1

What it is

Statement coverage (also called line coverage) measures whether each executable statement in the code has been executed at least once during testing. It’s expressed as a percentage: statements executed ÷ total statements × 100.

It answers the question: is there any code we haven’t run at all? It doesn’t answer: have we tested all the logic?

Measuring it

Statement coverage is measured by code coverage tools (Istanbul/nyc for JavaScript, JaCoCo for Java, Coverage.py for Python, etc.). These tools instrument the code and report which lines were hit during your test suite.

Worked example

Consider this function that calculates a discount:

Code with statement coverage analysis
function getDiscount(user, total) {
  let discount = 0;                    // S1 — always executed
  if (user.isMember) {                 // S2 — decision point
    discount = 0.10;                   // S3 — only if member
    if (total > 100) {                 // S4 — only if member
      discount = 0.15;                 // S5 — only if member AND total > 100
    }
  }
  return discount;                     // S6 — always executed
}
Coverage achieved by test input
Test inputStatements hitCoverage
Non-member, total = 50S1, S2, S650%
Member, total = 50S1, S2, S3, S4, S683%
Member, total = 150S1, S2, S3, S4, S5, S6100%

Notice: a single test with member, total = 150 achieves 100% statement coverage. But it doesn’t test the non-member case at all.

The limits of statement coverage

  • 100% statement coverage doesn’t mean all logic is tested. A single test that executes all statements may never test the false branch of any decision.
  • It doesn’t find missing code. If a required validation was simply never written, it won’t show up as uncovered.
  • It doesn’t test combinations. Each statement is hit once — not every combination of conditions.

Coverage is a floor, not a ceiling. 100% statement coverage is a minimum bar, not proof the code is correct. Teams that treat it as a quality target are measuring the wrong thing.

ISTQB mapping

ISTQB CTFL v4.0 reference
RefTopic
4.3.1Statement Testing and Coverage
FL-4.3.1 K2Explain statement testing and statement coverage
FL-4.3.1 K2Explain the reasons for measuring statement coverage

Branch coverage is stronger — it requires both the true AND false outcomes of every decision to be exercised. Statement coverage subsumes statement execution; branch coverage subsumes statement coverage. For most production code, branch coverage is the minimum target.

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

Try It — Calculate statement coverage

A NZ GST validation function has 7 executable statements (S1–S7). A test suite runs three tests. Work out which statements each test hits, then calculate coverage.

Function: validateGST(amount, isGSTRegistered)
function validateGST(amount, isGSTRegistered) {
  if (amount <= 0) {                  // S1
    return 'Invalid amount';           // S2
  }
  let gst = 0;                         // S3
  if (isGSTRegistered) {              // S4
    gst = amount * 0.15;              // S5
  }
  let total = amount + gst;           // S6
  return total;                        // S7
}
TestamountisGSTRegisteredStatements hit% coverage
Test 1-5false
Test 2100false
Test 3200true

After all 3 tests, what is the combined statement coverage? %