Unit tests check one small piece, integration tests check pieces working together, and end-to-end tests check the whole real app.
The three types:
- A unit test checks one small piece in isolation, such as a utility function, a reducer or a custom hook.
- An integration test checks several pieces working together. For example: a form component with its validation, its child components and a mocked network layer.
- An end-to-end (E2E) test drives the real app in a real browser, the way a user would. It usually runs against a running backend.
As you move from unit to E2E, tests get slower and cost more to maintain. But they give more confidence that the app really works.
How I balance them in a React app:
- I write most tests as integration tests with React Testing Library (RTL). I render a feature and interact with it like a user.
- I add unit tests for tricky pure logic.
- I add a small set of E2E tests with Playwright for the critical journeys, such as sign-up, login and checkout.
- A unit test checks one function, hook or component in isolation.
- An integration test checks several units together, for example a feature rendered with RTL and a mocked network.
- An E2E test runs the real app in a real browser, like a user.
- The trade-off is speed and cost against confidence.
- Put most weight on integration tests, and add a few E2E tests for critical flows.