Yeda AI Tips · #085

Español

100% Test Coverage Is a Red Flag, Not a Badge

One hundred percent test coverage is a red flag, not a badge. Martin Fowler put it bluntly: he'd "be suspicious of anything like 100% — it would smell of someone writing tests to make the coverage numbers happy, but not thinking about what they are doing." When the number becomes the goal, teams write tests for getters, config glue, and generated code — effort spent exactly where bugs don't live.

What coverage actually measures

Coverage tells you which lines (or branches) your tests executed. It says nothing about whether they asserted anything useful. A test that calls a function and checks nothing at all still turns its lines green. That's why coverage is best used as a detector of untested code, not a score of test quality: a low number is a real warning; a high number proves very little.

The 80 / near-100 split

Instead of one suite-wide target, split your codebase into two tiers:

TierTargetMetricExamples
Everything~80%statement coveragehandlers, UI glue, utilities
Critical pathsnear 100%branch coverageauth, payments, data mutation

The ~80% overall figure keeps the suite honest without forcing tests onto trivial code. The near-100% branch target goes only where a missed edge case costs real money or real data: authentication and authorization decisions, anything that moves money, and any code that mutates persistent state. Fowler's own ballpark for thoughtfully tested code is "upper 80s or 90s" — reached as a consequence of good testing, never mandated as a quota.

Enforce the split in CI, not in code review

Modern tools support tiered thresholds directly, so the policy is a config file rather than a reviewer's memory. Jest takes per-glob thresholds — global floor, per-path ceiling-pushers:

coverageThreshold: {
  global: { statements: 80 },
  './src/auth/':     { branches: 100 },
  './src/payments/': { branches: 100 },
}

Jest fails the run if any tier misses its own number; patterns are checked independently of the global floor.

Python (coverage.py): enable branch measurement with coverage run --branch (or branch = true under [run] in the config), and set fail_under in the [report] section — coverage exits with status 2 if the total lands below it. Run a second, stricter config scoped to your critical packages via include to enforce the near-100% tier.

Power-user moves

The takeaway

Coverage is a tool, not a trophy. Aim for roughly 80% statement coverage suite-wide, demand near-100% branch coverage on auth, payments, and data mutation, and wire both tiers into CI so the standard enforces itself. Your tests concentrate where a bug actually hurts — and you stop gaming a suite-wide number nobody should trust.

Resources

Building an AI feature? Yeda AI designs, audits, and ships production LLM systems.

Talk to us · Read the blog