The test pyramid — many unit tests, fewer integration tests, few end-to-end tests — is quoted as though the ratios were derived from something. They were not. It is a heuristic about cost and speed, and it is a reasonable default.
But it is a default, and most teams never check it against their own evidence.
The exercise
Open your last twenty incidents, bugs, or hotfixes. For each one, answer a single question: what kind of test would have caught this before it shipped?
Categorise honestly:
- A unit test — logic inside a function was wrong
- An integration test — two components disagreed about a contract
- An end-to-end test — the behaviour only breaks in a real browser or a real flow
- A contract test — an external service changed
- None of the above — a config error, an infrastructure failure, a data problem
That last bucket matters, and it is usually larger than people expect. If a third of your incidents are configuration, no test distribution fixes them and you should be spending that effort on deploy validation instead.
What teams usually find
Three patterns come up repeatedly.
The integration-heavy team. Their bugs are almost all seams — an API returning a shape the frontend did not expect, a migration that broke a query, an enum value nobody handled. They have thousands of unit tests, excellent coverage, and their bugs live in the gaps between the units. The pyramid told them to build more of what was already working.
The end-to-end-heavy team. Their failures are in real browser behaviour, real devices, real user flows. The slow expensive tests at the top of the pyramid are the ones earning their keep, and they have spent two years feeling guilty about an inverted pyramid that is correct for their product.
The config team. Half their incidents are not test-shaped at all. Their effort belongs in staged rollouts, health checks, and making bad configuration refuse to boot.
The point is not that the pyramid is wrong
For many teams it is roughly right, and if your evidence produces a pyramid then you have earned it rather than assumed it.
The point is that the shape should be an output of your failure history, not an input from a diagram drawn about somebody else's system in 2009.
Doing it continuously
Add one line to your incident template: what kind of test would have caught this?
After a year you have a distribution derived from your own product rather than a convention. It costs one line and it is the most useful testing metric I know of — considerably more useful than coverage percentage, which tells you what ran rather than what was checked.
Top comments (0)