tezvyn:

React Testing Library Queries: Find Elements Like a User

AI-drafted, machine-checkedSource: testing-library.combeginner

React Testing Library queries find elements by simulating how users see your UI, not by implementation details. Prioritize user-facing attributes like `getByRole` or `getByLabelText`.

WHY IT EXISTS Traditional tests often selected elements by CSS classes or IDs, which are implementation details. If a developer refactored the styles, the test would break even if the user experience was identical. React Testing Library solves this by providing queries that find elements the way a user would, making tests more stable and meaningful.

THE MENTAL MODEL Think like a user, not a developer. A user finds a button by its text ("Submit"), not its class name (".btn-primary"). They find an input field by its associated label ("Username"), not its ID. Your tests should use these same user-facing attributes. This forces you to build more accessible applications and makes your tests resilient to refactoring.

HOW IT WORKS The library offers three main query variants, each for a different scenario:

getBy...: Synchronously finds an element. It throws a descriptive error if no element or more than one element is found. Use this for elements you expect to be on the page when the test runs.

queryBy...: Synchronously looks for an element. It returns null if no element is found, making it perfect for asserting that something is not visible. It still throws an error if more than one match is found.

findBy...: Asynchronously finds an element. It returns a Promise that resolves when the element appears, retrying for a short period. Use this for elements that show up after an API call, timer, or animation.

Each variant also has a plural version (getAllBy, queryAllBy, findAllBy) to work with arrays of elements.

WHEN TO USE IT Always select elements based on the recommended priority guide, which mirrors the user experience. First, try getByRole to find elements by their accessibility role. For form elements, use getByLabelText. If that's not an option, fall back to getByPlaceholderText or getByText. These queries ensure your tests are robust and user-centric.

WHEN NOT TO USE IT Avoid using getByTestId as your primary selection method. It's an "escape hatch" for when no other user-facing attribute is available, but overusing it couples your tests to implementation details that users don't see. If you can't find an element with a standard query, it often signals an accessibility issue in your component that should be fixed.

ONE CANONICAL EXAMPLE A common pattern is to test for an element's absence, then its appearance. First, you might render a component and use screen.queryByText('Item saved!') to assert the result is null, confirming a success message isn't there yet. After simulating a user action like clicking a save button, you would use await screen.findByText('Item saved!') to wait for the message to appear asynchronously before asserting it's in the document.

Read the original → testing-library.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.