13 — Testing React — RTL, Jest, Vitest, Playwright, and the Pyramid
A pile of tool names was how React testing felt until I matched each one to a rung on the pyramid. The framing that organized it: pick the tool by what you're testing, and match it to the testing pyramid. [1] Unit logic runs in Vitest or Jest. Component behavior runs in React Testing Library. Full user flows through a real browser run in Playwright or Cypress. Each layer does a job the others can't, and pretending one tool covers everything is how test suites get slow, brittle, or both.
The testing pyramid, briefly
The pyramid is the way of thinking: a wide base of fast, cheap unit tests, a middle layer of integration/component tests, and a small apex of slow, expensive end-to-end tests [1]. The economics are the point — unit tests run in milliseconds and give precise failure pointers; E2E tests run in seconds, exercise the whole stack, but flake more and pin down less when they fail. A healthy suite is mostly the bottom, some of the middle, and a few of the top.
The unit layer: Vitest and Jest
For testing pure logic — a reducer, a utility function, a custom hook's internals — a JavaScript test runner is the tool. The roadmap lists both Vitest and Jest [2][3].
- Jest is the established framework — simple, works with Babel/TS/React, matcher-rich, and the historical default for React projects [3].
- Vitest is the Vite-native successor — fast, ESM/TS/JSX out of the box, and a Jest-compatible API so the migration is small [2].
The choice tracks the build tool: if the project is on Vite (which it should be — see the tooling notes), Vitest is the natural fit and shares the same config. For legacy create-react-app codebases, Jest is what's there. Both run isolated unit tests against pure functions, and both can render components with React Testing Library.
The component layer: React Testing Library
React Testing Library (RTL) is the standard for testing component behavior [4]. Its guiding principle flipped how I write component tests: "the more your tests resemble the way your software is used, the more confidence they can give you." [4] In practice, that means RTL renders the component into a real DOM and lets me interact with it the way a user does — finding elements by their visible text or label, clicking buttons, asserting on what's rendered — rather than testing the component's internal implementation.
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
test('submits the form', async () => {
render(<SignupForm />);
await userEvent.type(screen.getByLabelText(/email/i), 'a@b.com');
await userEvent.click(screen.getByRole('button', { name: /submit/i }));
expect(await screen.findByText(/welcome/i)).toBeInTheDocument();
});The deliberate constraint is that RTL doesn't expose component internals — no instance(), no direct state access. If I can't test something through the rendered output, the test is telling me the component's API is wrong. This is what makes RTL tests survive refactors: I can rewrite the component's internals entirely, and a behavior-based test still passes because the user-visible behavior didn't change.
The end-to-end layer: Playwright and Cypress
For testing full user flows through a real browser — load the app, sign in, fill a form, verify the database updated — an E2E framework is the tool. The roadmap lists both Playwright and Cypress [5][6].
- Playwright (Microsoft) drives Chromium, WebKit, and Firefox via the DevTools protocol, runs on all OSes, and is built for stable, parallelizable E2E tests [5]. It can see into and control the browser directly, which makes for reliable tests that simulate real user scenarios. It's the modern default for E2E.
- Cypress is the older incumbent — runs in the browser, has a polished interactive UI for watching tests run, and is well-loved for developer experience [6]. Its architectural choices (in-browser execution, historically single-browser) are the tradeoffs Playwright reacts to.
E2E tests are the apex of the pyramid precisely because they're expensive: they spin up a browser, often a test database, sometimes the whole backend. A suite of hundreds of E2E tests becomes slow and flaky. The discipline is to cover the critical user journeys (sign-in, checkout, the core flow) with E2E, and push everything else down to the component and unit layers.
How I use this
The rule I run is "push tests down the pyramid wherever possible." Pure logic — reducers, selectors, utility functions — gets a Vitest unit test, because it's fast and pins the failure to one function. Component behavior gets a React Testing Library test that interacts through the rendered output, because behavior-based tests survive refactors and catch the bugs users actually hit. E2E tests cover only the critical user journeys — sign-in, the main flow, checkout — because a suite full of E2E is slow and brittle. The tools I default to: Vitest (because my projects are on Vite), React Testing Library for components, and Playwright for E2E. Jest and Cypress I maintain in legacy codebases but don't pick for new work. The discipline isn't about which tool is "best" in isolation — it's matching each test to the layer that runs it fastest while still giving real confidence.
References
[1] BrowserStack, "Testing pyramid for test automation," browserstack.com, 2024. [Online]. Available: https://www.browserstack.com/guide/testing-pyramid-for-test-automation
[2] Vitest, "Vitest — a Vite-native unit test framework," vitest.dev, 2024. [Online]. Available: https://vitest.dev/
[3] Jest, "Jest — delightful JavaScript testing," jestjs.io, 2024. [Online]. Available: https://jestjs.io/
[4] Testing Library, "React Testing Library — intro," testing-library.com, 2024. [Online]. Available: https://testing-library.com/docs/react-testing-library/intro/
[5] Microsoft, "Playwright — fast and reliable end-to-end testing," playwright.dev, 2024. [Online]. Available: https://playwright.dev/
[6] Cypress, "Cypress — the web has evolved, testing should too," cypress.io, 2024. [Online]. Available: https://www.cypress.io/
[7] R. Wieruch, "How to use React Testing Library," robinwieruch.de, 2023. [Online]. Available: https://www.robinwieruch.de/react-testing-library/
Knowledge check · Question 1 of 5
The testing pyramid's central economic idea is:
Comments
Leave a Comment
You must be signed in to comment
0 Comments
No comments yet. Be the first to comment!