On this page
Unit vs Integration vs End-to-End Tests: What's the Difference?
Unit tests check one piece, integration tests check pieces together, and end-to-end tests check the whole user flow. A comparison table.
Quick answer
- Unit tests verify one function or module in isolation.
- Integration tests verify that multiple components work together.
- End-to-end tests drive the whole application like a real user, through the UI or API.
- The test pyramid says: many unit tests, fewer integration tests, fewest E2E tests.
The three levels compared
| Attribute | Unit | Integration | End-to-end |
|---|---|---|---|
| Scope | One function/module | Several components | Whole system, real flow |
| Speed | Milliseconds | Slower | Slowest |
| Fidelity | Low (isolated) | Medium | High (real usage) |
| Failure points to | Specific function | The seam between parts | The user-visible symptom |
| Count | Many | Some | Few |
What each catches
Unit tests catch logic errors cheaply and precisely — the discount math, the date parsing. Integration tests catch contract mismatches between components — a function that calls the database, a service that talks to a queue — where the bug lives in the boundary between pieces. End-to-end tests catch the failures that only appear when everything runs together: a login flow, a checkout, a deploy configuration.
The test pyramid
The classic guidance is a pyramid: a broad base of fast unit tests, a smaller middle of integration tests, and a narrow top of slow E2E tests. The shape reflects economics — unit tests are cheap and precise, E2E tests are expensive and fuzzy. You want many of the cheap ones and a few of the expensive ones.
Where this bites vibecoders
AI assistants default to few or no tests, and when asked, they often generate E2E-style tests that are slow and brittle — or a pile of unit tests that never exercise how the pieces fit. The practical target for a small app is the middle of the pyramid: a few E2E tests for the critical user journey, integration tests around your data layer, and unit tests for tricky logic. Coverage of the seams matters most.
Where AI coding assistants get this wrong
- Writing only unit tests and missing integration failures.
- Writing brittle E2E tests that break on unrelated UI changes.
- Skipping tests entirely unless explicitly demanded.
- Confusing the three levels and testing the wrong thing at the wrong level.
Checklist
- Use many unit tests for pure logic.
- Use integration tests around your data layer and external seams.
- Use a few E2E tests for the most important user journeys.
- Keep the pyramid shape: fast and many at the bottom.
- Make failures point somewhere specific, not just “it broke.”
FAQ
What is the test pyramid?
The test pyramid is a guideline for how many of each test type to write: many unit tests at the base, fewer integration tests in the middle, and fewest end-to-end tests at the top. It balances cost, speed, and precision.
Is a test that hits a real database a unit test?
No — once a test depends on a real database or external service, it’s an integration test, because it’s testing the interaction between your code and another component. Unit tests isolate the unit by replacing dependencies with fakes.
Which test type should I write first?
For new logic, unit tests first (fast feedback); then integration tests for the seams; then one E2E test for the critical path. The order follows the pyramid from cheap to expensive.