What and Why

Unit tests tell you that your code does what you wrote. Integration and end-to-end tests tell you that your system does what your users need.

You encounter integration failures when services that each passed unit tests fail to communicate correctly — wrong data formats, missing auth headers, database constraints violated, timeouts nobody tested. End-to-end failures show up when the full user flow works in isolation but breaks under real conditions.

These test layers exist because software doesn't run in isolation:

  • Unit tests: one function in memory, all dependencies mocked
  • Integration tests: two or more components wired together — your service + database, your service + a message queue
  • End-to-end tests: the full system, from API call to database write to response

Core Concepts

If unit tests pass everywhere, why do things still break in integration?

Because unit tests test each component against its assumed interface with the rest of the system. When two services meet, those assumptions collide with reality.

In the full tutorial

  • How It Works in Practice
  • Common Mistakes
  • Tradeoffs
  • Quick Reference

Glossary history

Click dotted jargon to save explanations here.