Introduction to Testing React Apps
In this page:
Why Test React Components
As an app grows, manually clicking through every feature after each change becomes slow and error-prone. Automated tests let you verify a component still behaves correctly in seconds, catching regressions (things that used to work but broke) before they reach real users.
Note: Start by testing your most critical user flows (like checkout or login) — you don't need 100% coverage to get real value from testing.
Warning: Tests run in a Node.js environment via Jest/Vitest, not in an actual browser — they can't run in this CDN-only preview sandbox.
Example: Why Test React Components
// Run in your local React project (npm install required)
// Button.test.jsx
import { render, screen } from '@testing-library/react';
import Button from './Button';
test('renders button text', () => {
render(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.
Testing Behavior, Not Implementation
Good React tests check what a USER would see or do — visible text, clickable buttons, form submissions — rather than internal details like a component's specific state variable names. This makes tests more resilient to refactoring, since they don't break just because you renamed an internal variable.
Note: If a test would need to change just because you refactored a component's internals (without changing its behavior), that's a sign the test is too implementation-focused.
Warning: Testing internal state directly (rather than through the rendered output) couples your tests tightly to implementation details that could change for unrelated reasons.
Example: Testing Behavior, Not Implementation
// Run in your local React project (npm install required)
// Good: tests what the user sees
test('shows error message on invalid email', () => {
render(<SignupForm />);
fireEvent.change(screen.getByLabelText('Email'), { target: { value: 'bad' } });
fireEvent.click(screen.getByText('Submit'));
expect(screen.getByText('Invalid email')).toBeInTheDocument();
});
The Testing Pyramid: Unit, Integration, E2E
Tests generally fall into three levels: unit tests check one small piece in isolation, integration tests check several pieces working together, and end-to-end (E2E) tests simulate a full real user flow through the entire app. Most teams write many unit tests, fewer integration tests, and only a handful of E2E tests.
Note: This shape (many unit, some integration, few E2E) balances speed (unit tests run fast) against realism (E2E tests catch more real-world issues but run slower).
Warning: Relying only on E2E tests makes your test suite slow and brittle; relying only on unit tests can miss bugs in how pieces interact together.
Example: The Testing Pyramid: Unit, Integration, E2E
// Run in your local React project (npm install required)
// Unit: tests one function/component in isolation
test('formatPrice formats correctly', () => { expect(formatPrice(5)).toBe('$5.00'); });
// Integration: tests a form + validation working together
// (see the previous section's example)
// E2E: tests a full flow (often with Cypress/Playwright)
// cy.visit('/signup'); cy.get('#email').type('[email protected]'); cy.get('button').click();
- Testing implementation details (internal state variable names) instead of what the user actually sees and does.
- Writing tests only for the happy path and never checking error/edge cases.
- Not running tests regularly, letting broken tests pile up unnoticed.
- Testing React apps typically involves a test runner (like Jest or Vitest) plus React Testing Library for rendering components.
- Good tests focus on user-visible behavior, not internal implementation details.
- Common test types include unit tests (one function/component), integration tests (several working together), and end-to-end tests (a full user flow).
- Tests catch regressions early, before they reach real users.
Requires npm install (Jest/Vitest + @testing-library/react) — tests run in Node, not this browser sandbox.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: