Skip to content

Justified Confidence — What Testing Actually Buys

The previous page, The Infinite Input Space, delivered a hard verdict: testing is sampling, and sampling can show the presence of bugs but never their absence. You cannot test your way to a proof. That leaves an obvious, uncomfortable question hanging in the air.

If a passing test suite does not prove the software is correct — if the green checkmark only means “none of the inputs we happened to try produced a wrong answer” — then what, exactly, are we buying when we spend a week writing tests? This page answers that. The thing you buy is not correctness. It has a name, it can be measured, and it can be bought well or badly. It is justified confidence.

“Is the software correct?” is the wrong question, because — as the last page showed — you can almost never answer it. It demands a fact about all 2^64 inputs, and you have observed a handful. Asking whether software is correct is like asking whether a coin is definitely fair after ten flips: the question is well-formed, but no finite amount of evidence settles it.

So reframe the goal. The right question is not “is it correct?” but:

“How confident am I that it does what it should — and can I justify that confidence to a skeptical reviewer?”

That reframing changes everything, because confidence is something you can actually have, measure, and defend. Correctness is a property of the code you almost never get to know. Confidence is a property of your belief, and belief responds to evidence. Every test you write, every review, every day it runs in production without incident — each is a piece of evidence that raises or lowers a belief you are allowed to hold.

The word that does the real work is justified. Anyone can feel confident. A developer who never tests anything can feel perfectly confident on the morning of a launch. The discipline of testing is not about feeling confident; it is about being able to justify the feeling — to walk into a room, face a hostile reviewer, and answer the question “why do you believe this works?” with evidence instead of a shrug.

feeling justified confidence
───────── ────────────────────
"I think it's fine" "It's fine, and here's why:
- 340 unit tests cover the parser,
including the 6 boundary cases
that historically broke
- the payment path has an
end-to-end test against a
sandbox gateway
- it ran 4 days in staging
with zero errors on real traffic"
not defensible defensible to a skeptic

The left column is a hope. The right column is an argument. Testing is the business of turning hopes into arguments. That is the entire product.

Keep an imaginary skeptic in your head. Their only job is to ask “how do you know?” after every claim you make. “The login works.” How do you know? “The refund can’t go negative.” How do you know? Every test you write is a pre-loaded answer to that question. A test suite is, quite literally, the written record of everything you can prove to the skeptic — and the gaps in it are exactly the claims you cannot yet defend.

This is why “it works on my machine” is not an argument. It is a feeling with no evidence attached. The skeptic dismisses it in one word: how?

Confidence is bought — and it has a price

Section titled “Confidence is bought — and it has a price”

Here is the shift that turns testing from a chore into engineering. Confidence is not free and it is not infinite. You buy it, one unit at a time, and every unit costs effort — time to write the test, time to run it, time to maintain it when the code changes, time to read it when it fails at 3 a.m.

That means every test has two numbers attached, not one:

  • What it buys — how much justified confidence it adds: how much of the input space’s behavior it newly covers, how likely the bug it guards against is, and how bad that bug would be.
  • What it costs — effort to write, time to run on every commit for years, and the maintenance drag of one more thing that breaks when the code moves.

A good test maximizes the first divided by the second: the most confidence gained per unit of effort spent. A test that takes thirty seconds to write and pins down a whole class of dangerous behavior is a bargain. A test that takes a day to write, reruns for years, and only re-checks a case three other tests already cover is a bad trade — it buys almost nothing and costs forever.

value of a test ≈ confidence it buys
──────────────────────
effort it costs to
write · run · maintain
great test: new behavior covered, cheap to write → high ratio
poor test: duplicates existing coverage, costly → low ratio

Notice this reframes the skill from the last page. There, a good test was a well-placed bet — one that samples a class of inputs that actually matters. Now we can say why it is good in economic terms: a well-placed bet buys a lot of confidence, and a redundant bet buys almost none, for the same price. The two views are the same coin.

Diminishing returns: the first test is worth a hundred of the thousandth

Section titled “Diminishing returns: the first test is worth a hundred of the thousandth”

Confidence bought per test is not constant. It falls off a cliff as you write more tests. This is the single most important economic fact about testing, and most teams never say it out loud.

Picture the confidence you have in a brand-new, completely untested module. It is near zero. Now write the first test — say, the happy path: the normal input, the expected output. That one test is enormous. It proves the code runs at all, that the wiring is connected, that the most common case in production works. You went from “I have no idea if this even executes” to “the main thing it’s for, works.” That first test bought a massive slice of confidence.

Write the second and third — a boundary, an error case. Still valuable; each covers a distinct class of behavior the first missed. But by the fiftieth test in the same module, you are testing increasingly obscure combinations, and each new one nudges your confidence by a sliver. By the thousandth, you are re-checking cases that three other tests already imply. The marginal test buys almost nothing.

confidence
100% ┤ ● ● ● ● ● ← thousandth test
│ ● ● adds a sliver
│ ●
│ ●
│ ● ← each early test
│ ● buys a big jump
│ ●
│ ●
0% ┤ ● ← first test: huge
└─┬───┬───┬───┬───┬───┬───┬───► tests written
1 5 10 50 100 500 1000
the curve is steep at the start and flat at the end.
the same effort buys wildly different amounts of
confidence depending on where you are on the curve.

The curve has a brutal practical meaning: the first few tests on any piece of code are almost always worth writing, and past some point, more tests on the same code are money that would buy far more confidence spent elsewhere. Chasing 100% coverage on a module you already have ten good tests for is climbing the flat part of the curve — real effort, near-zero return. That same effort spent writing the first test for an untested module next door is on the steep part, buying a huge jump. Testing well is largely about staying on the steep part of the curve, everywhere, instead of grinding the flat part somewhere.

There is a second dimension the counting so far has ignored, and it is just as important as how much confidence you buy: confidence about what?

Confidence that the checkout flow correctly charges a customer is worth more — often thousands of times more — than confidence that a tooltip renders the right shade of grey. Not because the tooltip test is harder or the payment test is cleverer, but because the consequence of being wrong is wildly different. A wrong charge loses money, breaks trust, and may be illegal. A wrong tooltip is a shrug.

So a unit of justified confidence is not a flat currency. It is weighted by what it protects:

value of confidence ≈ (how sure you are) × (how much
it matters
if you're wrong)

This is why two teams with identical test counts can have wildly different real safety. One spent its tests on the payment path, the auth boundary, the data-deletion flow — the places where being wrong is catastrophic. The other spent the same tests achieving beautiful coverage of formatting helpers and tooltip text. Same number of green checkmarks; profoundly different confidence where it counts. The green count is a vanity metric; the question is always green about what?

The practical rule falls straight out: spend your testing budget where being wrong hurts most. Buy the expensive, high-confidence tests — end-to-end, adversarial, exhaustive-at-the-boundary — for the payment path, the security boundary, the irreversible action. Buy cheap, thin confidence for the tooltip. Deliberately under-test the things that don’t matter, so you can over-test the things that do.

If confidence is bought per unit of cost, falls off with diminishing returns, and is worth more on some paths than others, then the question “how much testing is enough?” is not a moral question or a coverage number. It is an economic question:

Keep buying confidence — on the highest-consequence paths first — until the next unit costs more than the risk it removes is worth. Then stop, and spend the effort where it buys more.

Written out, “enough” is the point where the marginal test’s cost exceeds the marginal risk it retires. Under-testing leaves cheap, high-value confidence unbought — bugs ship that a five-minute test would have caught. Over-testing grinds the flat part of the curve — effort poured into confidence you already had, on things that barely matter. Both are waste; they just fail in opposite directions.

This page has given you the frame — confidence, cost, diminishing returns, weighting by consequence. It has not given you the method for actually deciding where the line sits for a given feature. That method has a name — risk-based testing — and it is the subject of How Much Testing Is Enough?, the page that closes this Part. Everything between here and there (the cost of a bug, verification vs validation, quality and QA, the oracle problem) sharpens one of the terms in the equation above.

  • Why does it exist? Because correctness is unprovable for real software (the infinite input space), the goal has to be something you can achieve. Justified confidence exists as the honest, attainable substitute for the certainty you can never have.
  • What problem does it solve? It replaces an unanswerable question (“is it correct?”) with an answerable one (“how sure am I, and can I defend it to a skeptic?”), and it gives you a currency — confidence bought per unit of cost — for deciding where testing effort should go.
  • What are the trade-offs? Confidence is never certainty; a defensible belief can still be wrong. Buying it costs real effort, that effort has sharply diminishing returns, and you must consciously weight it by consequence — none of which a raw coverage percentage captures.
  • When should I avoid it? When failure is catastrophic and the domain is small enough to prove correct outright — avionics, cryptographic cores, life-support loops. There, “justified confidence” is too weak a bar; pay for formal verification and demand proof, not evidence.
  • What breaks if I remove it? Drop the frame and testing loses its steering. You optimize the vanity metric — test count or coverage percent — grinding the flat part of the curve on things that don’t matter while the payment path goes under-tested. You end up with a lot of green checkmarks and confidence in all the wrong places.
  1. This page argues the goal of testing should be reframed from one word to another. Which two words, and why is the second one the achievable goal?
  2. What does the word justified add to confidence? Use the “skeptical reviewer” idea in your answer.
  3. State the value of a test as a ratio. What makes a test a good buy versus a poor one?
  4. Explain “diminishing returns” for testing a single module. Why is the first test often worth more than the thousandth, and what mistake does chasing 100% coverage encourage?
  5. Two test suites have the same number of tests, but one is far safer in practice. Give the reason this page offers, and state the practical rule it implies about where to spend testing effort.
Show answers
  1. From correct to confident. Correctness is a property of the code across all inputs, which the infinite input space makes practically unknowable. Confidence is a property of your belief, and belief responds to evidence — so it is something you can actually have, measure, and grow with each test. You reframe to a goal you can reach.
  2. Justified means the confidence is backed by evidence you can defend, not merely felt. The test is the standard: imagine a skeptic who answers every claim with “how do you know?” A feeling (“it works on my machine”) fails that test; a suite of tests is a pre-written, defensible answer. Testing is the business of turning hopes into arguments a skeptic would accept.
  3. value ≈ (confidence the test buys) / (effort to write, run, and maintain it). A good test buys a lot of new confidence — it covers a class of behavior nothing else does, or guards a likely and costly bug — for little cost. A poor test duplicates coverage you already have and/or costs a lot to write and maintain, so its ratio is low.
  4. The confidence bought per test falls sharply as you add more to the same module. The first test takes it from “no idea if this even runs” to “the main case works” — a huge jump; by the thousandth you are re-checking cases other tests already imply — a sliver. Chasing 100% coverage pushes effort onto the flat part of the curve (near-zero return) instead of the steep first-test part on some other untested module, where the same effort would buy far more.
  5. Not all confidence is equal — a unit is worth (how sure you are) × (how much it matters if you’re wrong). The safer suite spent its tests on high-consequence paths (payment, auth, irreversible actions); the other spent the same tests on low-stakes code like tooltip text. Practical rule: spend the testing budget where being wrong hurts most — over-test the catastrophic paths, deliberately under-test the trivial ones.