Contents

What the testing pyramid is

The testing pyramid is a model describing the proportions in which you should write tests at different levels. Mike Cohn introduced it, and it's been an industry reference point ever since.

The idea is simple: tests come in levels, and the lower the level, the more of those tests you should have.

        /\
       /e2e\        few, slow, expensive
      /------\
     / integ. \     some
    /----------\
   /    unit    \   many, fast, cheap
  /--------------\
  • Unit tests check a single function or class in isolation. They run in milliseconds and don't depend on a database, network, or filesystem.
  • Integration tests check how several components work together: a repository against a real database, or two services talking over HTTP.
  • E2E tests (end-to-end) run a whole scenario the way a user would: open the page, fill the form, click the button, see the result.

Why these proportions

Each level pays a price along three axes: speed, maintenance cost, and stability.

Speed. A thousand unit tests finish in a couple of seconds. A thousand e2e tests can run for half an hour. The longer the run, the less often developers trigger it — and the later they catch bugs.

Maintenance cost. A unit test breaks only when the logic of a specific piece of code changes. An e2e test breaks at the slightest thing: a moved button, changed copy, an updated external service. Every such failure has to be triaged by hand.

Stability. A unit test is deterministic: the same input always yields the same result. E2e depends on a dozen factors — timings, database state, the network — so it's prone to intermittent failures (flaky tests).

The conclusion: keep the bulk of your logic verification at the cheap, fast level, and reserve costly e2e tests for a few genuinely critical user flows.

What the pyramid does NOT mean

A common misreading is "e2e tests aren't needed." They are. Their job is to confirm the system is wired together and the key user path works — not to cover every conditional branch.

A second misreading is that the numbers per level are absolute. The pyramid is about orders of magnitude, not exact counts. If you have 800 unit, 120 integration, and 15 e2e tests, your proportions are healthy, even if a textbook draws it differently.

Antipattern 1: the inverted pyramid

The most painful case is when the bulk of tests sits at the top.

  \--------------/
   \    e2e     /     WAY too many
    \----------/
     \ integ. /
      \------/
       \unit/         too few
        \/

This happens when a team tests only through the UI, ignoring the lower levels. The symptoms are familiar to anyone who's lived through it: the suite runs for an hour, half the failures are false alarms, and finding the cause of a real bug in a pile of e2e logs is nearly impossible.

Antipattern 2: the ice cream cone

Even worse is when manual testing is piled on top of an inverted pyramid.

      manual testing         <- the bulk
  \--------------------/
   \       e2e        /
    \----------------/
     \   integ.     /
      \-----unit---/

Almost no automated tests at the bottom, a bit of e2e in the middle, and an army of manual checks before every release. It's slow, doesn't scale, and burns people out. Usually a sign that automation started late and gaps are being patched by hand.

Keeping the pyramid healthy

A few practical guidelines:

  1. Cover new logic with unit tests right away. The closer the test is to the moment the code is written, the cheaper it is.
  2. Ask: can this be checked one level down? If a business rule is verified by a unit test, don't duplicate it in e2e.
  3. E2e only for critical paths. Login, checkout, payment. Not "every possible filter combination."
  4. Track feedback, not coverage percentage. A good pyramid answers "did it break or not?" in seconds, not in half an hour.

A modern take: the testing trophy

Kent C. Dodds proposed an alternative — the "testing trophy" — where the center of gravity shifts to integration tests. That makes sense for frontends and stacks where isolating modules gives little confidence and the seams between components matter more.

But this isn't a rejection of the pyramid, it's tuning it to context. The core principle is unchanged: lots of cheap, fast tests; few expensive, slow ones. The exact profile depends on where the real risk lives in your system.

Wrapping up

The testing pyramid isn't dogma with exact numbers — it's a reminder of the tradeoff between speed, cost, and stability. Keep the foundation on fast unit tests, add integration tests where the seams matter, and save e2e for a handful of key scenarios. Then your tests help you instead of becoming a chore everyone dreads running.

Share: