Why Testing Is Worth It
The real return on test investment — and the tests that actually prevent regressions
Most developers write no tests because they believe tests slow them down. They are right about badly-written tests. They are wrong about well-chosen tests. The discipline is not "write all the tests" — it is "write the tests that prevent the bugs that cost the most." This lesson gives you the framework to make that judgement.
The cost of no tests
Tests are like load-bearing walls — you only notice they are missing when something collapses
You can renovate a house quickly by removing walls. It is fast. It feels productive. But some of those walls held up the ceiling. Without tests, every refactor is a renovation where you cannot tell which walls are load-bearing. Eventually something collapses in production, at the worst possible time.
The testing pyramid
- Unit tests (base — most tests here) — Test a single function in isolation. Fast (milliseconds), cheap to write, easy to diagnose. Best for pure functions, validation logic, and business rules.
- Integration tests (middle) — Test multiple units working together, usually including a database or external service. Slower than unit tests but validate the connections between layers.
- E2E tests (top — fewest tests here) — Test the whole application through a real browser. Slowest and most brittle. Reserve for critical user journeys only: sign up, pay, core feature.
What is actually worth testing
- Business logic with multiple conditions — If a function has more than 2 branches (if/else/switch), write a unit test. Every branch is a regression risk.
- API routes and database interactions — Integration tests. Does the route correctly validate input, hit the database, and return the right response?
- Critical user journeys — E2E. Sign up, log in, complete a purchase — the flows where a bug means lost revenue.
- Bug reproductions — Every time you fix a bug: write a test that would have caught it first. Add it to your test suite. That bug can never silently return.
What is not worth testing
- Framework glue code — Testing that React renders a component, that a button has a class, or that a prop is passed. You are testing the framework, not your logic.
- Implementation details — Tests that break whenever you rename a function or restructure a component, even if the behaviour did not change. These create maintenance burden without preventing regressions.
- Third-party libraries — Do not test that Stripe charges the card correctly. Test that you call Stripe with the right arguments.
Try this
Look at the last three bugs you fixed in production. For each one: could a unit test have caught it? An integration test? Write one test for the most impactful of the three. You now have a regression test for your most painful bug. That is a better return on time than any general "add more tests" goal.