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
| Risk | Cheapest layer that sees it |
|---|---|
| Rounding error in a price rule | Unit test |
| Wrong column name in a SQL query | Integration test with a real database |
| Another team renamed a JSON field | Contract test |
| Button hidden behind a cookie banner | End-to-end test |
| Query fine alone, slow under 200 users | Load test |
| Bad config in one region only | Canary 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.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.