A practical guide to React Testing Library — how to query, fire events, and write tests that reflect real user interactions.

Abdur Razzak
Full-Stack Web Developer
React Testing Library is built around one core principle: test your components the way users use them. This means querying elements by their role, label, or text content — not by implementation details like class names or component state. Tests written this way are resilient to refactoring, catch real user-facing bugs, and serve as living documentation of your component's behavior.
React Testing Library comes pre-configured in Create React App and Next.js projects. Import render and screen from @testing-library/react. Use screen.getByRole('button', { name: /submit/i }) to find a button by its accessible name. Use userEvent.click() from @testing-library/user-event for realistic user interactions. Prefer getBy queries for elements you expect to be there, and queryBy for elements you expect to be absent.
The query priority order is: getByRole (best — uses ARIA), getByLabelText (good for form inputs), getByPlaceholderText, getByText, getByDisplayValue, getByAltText, getByTitle, and lastly getByTestId (last resort). Avoiding getByTestId keeps your tests from breaking when you restructure the DOM, since test IDs are implementation details that real users never see.
Use waitFor() to wait for async state changes, such as after a form submission or data fetch. findBy queries (like findByText) are shorthand for waitFor + getBy and are cleaner for simple async assertions. Mock API calls with jest.fn() or msw (Mock Service Worker), which intercepts actual HTTP requests and returns mock responses — making your tests more realistic than manual mocking.
Use userEvent.type() to simulate keyboard input character by character, which fires all the same events as real typing (keydown, keypress, keyup, input, change). Always call await userEvent.setup() before interactions in modern versions of user-event. Test full form workflows: fill in fields, submit the form, and assert the success state or API call.
React Testing Library works with both Jest (the traditional choice) and Vitest (the modern, fast alternative for Vite-based projects). Configure jsdom as the test environment and set up @testing-library/jest-dom for helpful matchers like toBeInTheDocument(), toBeVisible(), and toHaveValue(). Aim for a test pyramid: many fast unit tests, some integration tests for user flows, and few slow E2E tests with Playwright.