React Best Practices

Chapter 7 · Practice 1 of 4

Test what the user sees, not component internals

From Testing React code

Why it matters

Tests that check internal state or call component methods break every time you refactor, even when the app still works. Test through the rendered output instead:

  1. Find elements by role and accessible name.
  2. Interact the way a user would, with user-event for typing and clicking.
  3. Assert on what appears on screen.

React Testing Library is built for this style. Query with getByRole('button', { name: 'Save' }) first.

Example

TSX
test('shows an error for an invalid email', async () => {
  const user = userEvent.setup();
  render(<SignUpForm />);
  await user.type(screen.getByRole('textbox', { name: 'Email' }), 'nope');
  await user.click(screen.getByRole('button', { name: 'Sign up' }));
  expect(await screen.findByRole('alert')).toHaveTextContent('valid email');
});