Test Pyramid
Mike Cohn's pyramid: many fast unit tests at the base, fewer integration, very few E2E. Avoid the ice-cream-cone anti-pattern.
Overview
The test pyramid
The test pyramid is Mike Cohn's mental model from Succeeding with Agile (2009) for distributing automated tests across levels of granularity. The shape is a triangle: widest at the base, narrowest at the top.
- Unit (base) — Many; milliseconds; isolated from external dependencies — Individual classes, functions, modules
- Integration / service (middle) — Fewer; seconds — Boundaries: database access, HTTP clients, message queues, with the system under test in a controlled environment
- End-to-end / UI (top) — Few; tens of seconds to minutes — The full system as a user would use it
> [!NOTE] The ~70% unit, ~20% integration, ~10% E2E split is frequently quoted. It is a heuristic, not a law.
Why the shape matters
Tests at different levels have different cost and signal characteristics.
- Speed — Milliseconds: a 10,000-test suite finishes in under a minute — Tens of seconds to minutes: a 10,000-test suite finishes never
- Determinism — Deterministic when written well — Fights asynchrony, network flakiness, environment drift, shared-state contamination; 1-5% flake is normal and considered very low
- Isolation of failure — The test identifies the failing component — Any of a dozen components, plus the environment, plus the test itself
- Maintenance — Stable against refactors that preserve function-level behavior — Stable against nothing: UI changes, latency tweaks, new feature flags break them
The ice-cream cone anti-pattern
The ice-cream cone (Alister Scott, 2012) is the inverted distribution: many manual and E2E tests, some service tests, few unit tests.
- QA teams own testing and gravitate to user-facing tests — Hour-long suites
- Record-and-playback E2E tools are easy to start with — 10-30% flake rates
- The superficial argument that E2E tests "test what users see, so they are more real"
Modern refinements
- Testing trophy (Kent C. Dodds), frontend — Static analysis at the base, then unit, a large integration layer, E2E at the top
- Honeycomb (Spotify), microservices — Mostly integration tests, few implementation-detail unit tests
- Diamond — Contract tests in the middle replace some integration tests
- Pact-driven contract tests — Verify consumer/provider boundaries without standing up the other service
Key concepts
- Test pyramid (Cohn 2009)
- Many fast unit tests at the base, fewer integration in the middle, very few E2E at the top. Heuristic ~70/20/10. The shape is essential; the exact percentages move per service. A pure data-transformation library is appropriately ~95% unit; a thin orchestrator is heavier on integration.
- Unit test
- Tests a single function, method, or class in isolation from external dependencies. Runs in milliseconds. Deterministic. Failure points to the offending unit. The base of the pyramid by volume.
- Integration test
- Tests a component plus one or more real dependencies (DB, message queue, HTTP client → mock server). Slower (seconds), still mostly deterministic. Catches failures unit tests cannot — schema mismatches, contract drift, transaction semantics.
- Contract test (Pact)
- Verifies the interface between two services without standing up both. Pact is the canonical tool. Sits between unit and integration; cheap and decoupled. Reinstates a healthy middle layer between unit and full E2E in microservice architectures.
- End-to-end (E2E) test
- Tests the full system as a user would, through real UI or API entry points, with real backing services. Slow, flaky, expensive — but verifies the whole stack. Use sparingly: only for critical user journeys that drive your SLOs.
- Ice-cream cone anti-pattern
- (Scott, 2012) Inverted distribution: heavy E2E, thin unit base. Slow suites, high flake, low signal. The most common test-strategy failure. Symptoms: 90-minute suites, 8% flake, "we retry failing tests three times," the team learns to ignore CI failures.
When to use it
- Designing the test strategy for any new service or feature — start with the pyramid as the default
- Auditing an existing test suite that takes 90 minutes and produces 8% flake — almost always an ice-cream cone
- Justifying investment in unit-test coverage to a team that "has E2E for everything"
- Picking what to test at which layer when adding a new feature spanning UI, API, DB, and integrations
Interview questions
- Explain the test pyramid and why the proportions matter.
- What is the ice-cream cone anti-pattern and why does it happen?
- Where do contract tests fit, and why are they increasingly popular?
Sign up free to read the full topic
More DevOps topics
- Terraform — Production Errors, Mistakes and Recovery
- Terraform & OpenTofu
- Terraform count vs for_each
- Terraform Essentials — Plan and Apply, Variables, Outputs, Data Sources, and Sharing State at Scale
- Terraform in CI/CD Pipelines
- Terraform Remote State — S3 + DynamoDB
- The C/C++ Compilation Model
- The flux CLI
- The Three Ways
- Toil Reduction & Automation Strategy
- Trunk-Based Development
- Trunk-Based Development with Continuous Deployment
Start free on Cariara · Coding problems · System design studio