Frontend engineer path · Shipping with confidence · Topic 15 of 17

What to automate: the pyramid and the trophy

Not started

Automated tests are a bet: you spend time now so you don't ship bugs later. A good strategy puts each check at the cheapest layer that can still catch the bug, automates what you would otherwise check by hand again and again, and leaves to people the exploring that scripts cannot do.

Why it matters: A suite aimed at the wrong layer ends up slow, brittle and ignored. People stop reading red builds, and real bugs get through.

  1. 1Cost against confidence

    Every test gives you some confidence and costs you something: time to write, time to run, and time to fix when it breaks for no good reason.

  2. 2The pyramid

    Lots of fast unit tests at the bottom, fewer integration tests in the middle, and only a handful of slow end-to-end tests at the top.

  3. 3The trophy

    Static checks at the base and most of the effort in integration tests, because those exercise the code the way it is really used and still run quickly.

  4. 4Push each check down

    Whichever shape you pick, test each risk at the cheapest layer that can still catch it.

1

How it works

The explanation, with examples you can run.

What is worth automating

Automate a check when it will run many times and a human would get bored or careless repeating it:

  • Regressions: anything that has broken before. Write the test that would have caught it before you fix it.
  • Critical paths: sign-in, payment, anything that loses data or money when it fails.
  • Logic with many cases: pricing rules, permissions, date handling, parsers.
  • Contracts between teams: the API shapes other services depend on.

Some things are not worth scripting: a one-off migration you will check once, a layout that changes every week, or anything the type checker or linter already catches. Exploratory testing, where a person tries to break things in ways nobody planned for, stays a human job. Automation frees time for it.

Two shapes

The test pyramid (popularised by Mike Cohn in Succeeding with Agile) says to write many small, fast unit tests, fewer integration tests, and very few end-to-end tests, because the higher you go the slower, more brittle and harder to debug the tests get. Its failure mode is the ice cream cone: mostly UI tests and manual checks, with a thin layer of unit tests underneath.

The testing trophy (Kent C. Dodds) adds static analysis (types, lint) as the base and makes integration tests the widest part. The reasoning is that a test that uses your code the way real callers do gives more confidence per test, and modern tools make those tests fast enough to run all the time.

The two shapes agree more than they argue. Both say end-to-end tests should be few, and both say a check belongs at the lowest layer that can see the bug. They disagree mainly about what counts as a "unit" and how much to isolate it.

Matching the bug to the layer

RiskCheapest layer that sees it
Rounding error in a price ruleUnit test
Wrong column name in a SQL queryIntegration test with a real database
Another team renamed a JSON fieldContract test
Button hidden behind a cookie bannerEnd-to-end test
Query fine alone, slow under 200 usersLoad test
Bad config in one region onlyCanary and synthetic checks in production

When a bug escapes, ask which layer should have caught it, and add the test there, not one layer higher just because that is easier to write.

2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.A discount is calculated wrongly when the cart has zero items. Where is the cheapest place to catch that?
  2. 2.A team has hundreds of UI tests, a few unit tests and a lot of manual regression testing. What is the usual problem with this "ice cream cone" shape?
  3. 3.Which layer does the testing trophy put the most effort into?

0 of 3 right so far. Get all three to finish this topic.