Build1 distinct publisher3 min readUpdated
One engineer's billing flow broke on launch day at 87% coverage. The metric was doing exactly what it was built to do, which is why the fix starts with incentives rather than tooling.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
An engineer writing on dev.to describes shipping a billing flow that broke on launch day while the suite sat at 87% coverage, and argues the failure was not in the unexecuted remainder but in what the covered lines were actually checking [1][1]. That is worth attention because coverage percentage is the answer most teams give when asked whether their testing is working, and the metric records one thing: which lines ran during the test run [3].
That is the whole definition. If a line executed, it counts [3]. Coverage does not know whether the test asserted anything meaningful about that line, whether both branches of a conditional were exercised, or whether the inputs that actually cause failures were ever tried [4]. A test that calls a payment function and checks that the response is not null covers the same lines as one validating transaction ID, amount, currency, error code and retry behaviour. The tool scores them identically [5].
The empirical record, as the post summarises it, is not kind to the metric. Kochhar et al. in 2017 looked at coverage against post-release bug counts across 100 large open-source Java projects and found the coverage of existing test suites had an insignificant correlation with bugs found after release [6]. Inozemtseva and Holmes separately found that line coverage correlates least with real defect detection among the available options [7].
So the gate is a proxy, and Goodhart's Law applies: when a measure becomes a target, it stops being a good measure [8]. The behaviour that follows is not carelessness, it is arithmetic. Under delivery pressure, the cheapest route to a number is the happy path: those tests are quick to construct, run fast, and each one sweeps a high line count because it walks the main execution path [9]. Error handling, retry logic, fallback and timeout behaviour sit in branches that need deliberate setup, and those are precisely where the expensive bugs live [10]. Boundary inputs, nulls, empty strings, Unicode, maximum lengths, each cost a separate test while covering nearly the same lines as one ordinary input [11]. A conditional reads as covered the moment either side executes, so a function that treats admin and guest differently can show green having only ever seen one role [12].
The result the author describes is a suite at 85% where the safe parts are tested three times over and the failure-prone parts carry one shallow test each [13]. The post also claims that teams with high line coverage and low integration validation have been observed producing more than double the production incidents of teams with lower but more balanced coverage; that figure is the weakest link in the argument, since the piece flags it as an assumption rather than a sourced result [14][15].
Strip the metric criticism away and the operational point stands: this is an incentive that management installed, and engineers responding to it rationally [16]. Changing the tool without changing what gets rewarded moves the gaming somewhere else.
What to watch on your own team: whether the error paths, retries and timeouts have tests at all, since coverage will not tell you [10]; whether conditionals have been exercised on both sides rather than counted once [12]; and whether release sign-off still hinges on a percentage. The author's framing is that this is a management decision before it is a tooling decision [15], and that ordering is testable. If the gate stays, the tests will keep being written for the gate.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
A 2017 study by Kochhar et al. examined the correlation between code coverage and actual bug rates across 100 large open-source Java projects, and found that the coverage of existing test suites has an insignificant correlation with the number of bugs found after release.
Inozemtseva and Holmes found that line coverage is the metric that correlates least with real defect detection compared to other available options.
The author writes: 'I had 87% coverage, and we still broke the billing flow on launch day. Not because of a gap in the percentage. Because 87% was covering the wrong things. The tests were written to pass a gate, not to catch a failure.'
Coverage percentage tracks which lines of code were executed during a test run. If a line ran, it counts as covered. The source states that this is the complete definition.
Coverage does not measure whether the test asserted anything meaningful about the line, whether both branches of a conditional were exercised, or whether the specific inputs that cause failures were ever tried.
A test that calls a payment function and checks 'assert response is not None' covers the same lines as a test validating the transaction ID, amount, currency, error code and retry behaviour; the coverage tool treats them identically.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Definitional claims solid, quantitative claim self-disclaimed
The mechanical claims about what line coverage does and does not measure are self-evidencing and uncontroversial, and two peer-reviewed findings are cited by author and year. But there is exactly one source, the study citations carry no titles, venues, links or effect sizes, the central anecdote is unverifiable first-person, and the one quantified outcome claim is withdrawn to 'directional' by the author's own note. Enough to support the framing; not enough to support the numbers.
No adoption or usage data supplied
The supplied material is an argumentative post. It asserts in passing that coverage is the most popular quality metric in software engineering, but supplies no survey, telemetry, repository, release, or deployment data on how many teams enforce coverage gates, at what thresholds, or how many have adopted mutation testing instead. No adoption observation can be recorded without inventing facts.
Mildly overstated, largely self-corrected
The headline framing ('structurally broken', 'making your tests worse') runs ahead of a one-source evidence base, and 'more than double the production incidents' is a precise-sounding multiplier with no controlled study behind it. The overstatement is small rather than large because the author appends an assumption note that downgrades that figure to directional evidence, and because the definitional core of the argument is genuinely airtight.
QA-practice byline promoting testing investment and mutation testing
The post is the fourth instalment of a series that explicitly 'built the investment case for testing', published on a community platform under a QA-practice handle, and it closes by advancing mutation testing as the honest replacement metric. The author therefore benefits from readers concluding their current testing measurement is inadequate. This is disclosed only implicitly through the byline and series framing; there is no stated commercial relationship, so the incentive is moderate rather than severe, and it is partly offset by the self-flagged assumption note.
Confident on mechanics, weak on magnitude
Confidence is high that the described coverage mechanics and gaming dynamics are real, since they follow from the definition of line coverage and are consistent with the two cited studies. Confidence is low on any magnitude claim — incident multipliers, how prevalent gate-gaming is, or what switching to mutation score would cost — because the cluster has one source, no adoption data, and a self-disclaimed key statistic.
build
An AI test suite hit 94% coverage and missed the one branch that mattered1 distinct publisher
build
The check that never fires: why every agent-built detector needs a negative control1 distinct publisher
build
Benchmarks are contaminated by design: your eval set should be one nobody has published1 distinct publisher
build
Your REPL Is Not A Container: Put Free-Variable Checks In CI Before Generated Code Ships1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 20, 2026