# Which Test Catches the Production Bug?

> The real payoff of unit and integration tests: which one actually prevents production bugs, and where to spend your testing budget.

- Type: Essays
- Published: 2026-10-24
- Tags: testing, quality, opinion
- Reading time: 3 min read
- Source: https://muhammetsafak.com/engineering/essays/integration-vs-unit-tests/
- Language: en-US
- Author: Muhammet Şafak

---
> **TL;DR:** In practice, many production bugs originate between components, and an isolated unit test mocks exactly the connection that breaks. Unit tests shine on pure, logic-heavy cores; integration tests check glue code against a real database and HTTP layer. Spend the test budget where bugs are born, and keep mocks for external dependencies such as a payment provider.

A feature with 100% unit test coverage broke in production on day one. The bug was inside no single unit; it was in the way two components talked to each other. Every unit had been tested individually, in isolation, flawlessly. The seam between the two was the one thing no test had ever seen.

"Which test would have caught this bug?" is the real question behind any testing strategy.

## Where real bugs are born

Trace your production bugs back honestly and many of them land on the same address: the space **between** components. A payload serialized wrong, a contract that doesn't line up, a transaction boundary drawn in the wrong place, a config difference across environments.

The isolated unit test mocks out exactly the piece that breaks. A test that mocks the database can't see a query written wrong. A test that mocks the HTTP layer can't catch a wrong status code. A test is only as good as the fake it puts in place of the real thing.

## What unit tests are for

This is not an argument against unit tests. Unit tests have a clear value: fast feedback on complex, pure logic. A calculation, an algorithm, a state machine, a pile of edge cases — testing those with isolated, fast tests is the right move. Hundreds of scenarios in seconds.

Unit tests shine when the **logic** is rich.

## What integration tests are for

Integration tests answer a different question: do the components actually work together? With a real database, a real HTTP layer, a real queue. Hitting an endpoint and verifying that the right row appears in the database exposes everything mocks would have hidden.

A typical web application is mostly **glue code**: take data, validate it, save it, return it. There's little logic and a lot of wiring in that code. Only an integration test exercises the wiring.

## Where the testing budget goes

The classic test pyramid puts a large number of unit tests at the bottom. But for a typical web application, integration tests give the highest payoff in bug prevention — because the bugs are born in the wiring.

A practical split: integration tests for the glue code; unit tests for the logic-heavy core. Piling isolated unit tests onto glue code raises [the coverage number](/engineering/essays/a-lean-testing-culture/) but doesn't protect production.


> **Tan:** When a bug escapes to production, write down which test would have caught it: unit or integration. After a few incidents, where the test budget should go stops being an argument and becomes a record. The question at the top of the piece could be the last item of every post-mortem.


## The mock trap

The most common mistake is mocking the thing that breaks. A test that mocks the database can never tell you a query is wrong — because that test has replaced the place the query goes with a fake. A query bug like an N+1 in [data-intensive systems](/engineering/systems/data-intensive-systems-breaking-points/) is only caught by a test that hits a real database.

Save mocks for the external things that you don't control and that are slow — a payment provider, say. Mocking your own database is, more often than not, cutting the test loose from reality.

---

"All tests are green" does not mean "production is safe." If you don't know which test prevents which bug, your test count isn't a source of confidence, it's a feeling.

Spend your testing budget where the bugs are actually born — in the space between components.

## Sources

- [TestPyramid](https://martinfowler.com/bliki/TestPyramid.html) — martinfowler.com
