Testing Fundamentals
Types of Tests: Unit, Integration, E2E
Understand when to write unit, integration, and end-to-end tests — and why the distinction matters.
Three Types of Tests
Not all tests are equal. Choosing the right type for each scenario determines whether your test suite is a valuable safety net or a slow, brittle burden.
Unit Tests
Unit tests verify a single function, class, or component in complete isolation. All external dependencies are replaced with mocks.
Characteristics: Very fast (milliseconds), very reliable, very cheap to write and maintain.
When to use: Business logic, utility functions, data transformations, algorithms, pure functions.
Integration Tests
Integration tests verify that multiple units work correctly together. They use real dependencies where possible — real database queries, real HTTP calls (to a test server), real file system.
Characteristics: Slower than unit tests (seconds), more realistic, catch interaction bugs.
When to use: API routes, database operations, service-to-service communication.
End-to-End Tests
E2E tests control a real browser and simulate real user actions against your running application.
Characteristics: Slow (seconds to minutes), most realistic, catch the bugs users would actually encounter.
When to use: Critical user flows: signup, login, checkout, core feature paths.
The Testing Trophy
Kent C. Dodds' "testing trophy" suggests writing MORE integration tests than the traditional pyramid suggests. Integration tests give the best return per test — more realistic than unit tests, faster than E2E.
Key Takeaways
- Unit tests verify isolated functions — fast, cheap, many of them
- Integration tests verify how components work together — more realistic, medium speed
- E2E tests verify complete user flows in a real browser — slowest, highest confidence, fewest needed
- The testing trophy: favor integration tests over unit tests where possible — better confidence per test
- Never test implementation details — test behavior (what the code does, not how it does it)
Example
// Three tests for the same feature at different levels