A team's test distribution is an inverted pyramid — many end-to-end tests, few unit tests. What does that cost, and what causes it?
Show the full answer Hide the answer
What it costs
1. Slow feedback. End-to-end tests need everything running. A suite dominated by them takes tens of minutes, so developers batch changes — which degrades review quality, bisection and conflict size.
2. Flakiness. Any component, any timing issue, any environment problem fails the test. A suite that fails for unrelated reasons trains everyone to re-run rather than investigate, at which point it catches nothing.
3. Unclear ownership. A failure in a shared end-to-end suite belongs to nobody, so it is nobody's priority.
4. Poor localisation. A failing end-to-end test says something is broken somewhere. A failing unit test says what is broken, where.
5. Combinatorial cost. The number of interaction paths grows combinatorially while the suite's value grows linearly.
What causes it
Usually the architecture, not the discipline. Teams write end-to-end tests because the units cannot be tested in isolation — components reach into shared state, depend on ambient configuration, or cannot be constructed without the world.
The second cause is that end-to-end tests are the ones that catch real defects in such a system, so the team is responding rationally to the evidence.
The fix
Address testability first, then rebalance. Injecting dependencies, giving components their own data, and removing ambient configuration is what makes fast tests possible — and no amount of test-writing discipline substitutes.
Then: contract tests to replace the expensive middle, verified in the provider's pipeline so a breaking change fails before merge with unambiguous ownership. This is the layer that removes most of the need for cross-service integration tests.
And keep a deliberately tiny end-to-end layer for critical journeys, which catches integration assumptions no contract expresses.
The shape worth aiming for
Not a strict pyramid — a large fast base, a substantial contract layer, and a small end-to-end tip. The proportions matter less than the property: feedback fast enough to run before every push, which is what keeps change size small.