React Testing Library Queries

React Testing Library provides semantic queries for selecting elements according to how users perceive the UI. Choosing the right query makes tests more representative of real user interactions and less coupled to implementation details.

React Testing Library queries locate elements in the rendered DOM. The preferred approach is to query for things a user can recognize, such as accessible roles, labels, visible text, and form values, rather than relying on component internals or CSS classes.

The main query families are `getBy`, `queryBy`, and `findBy`. `getBy` expects the element to exist immediately and throws when it cannot find a match; `queryBy` returns `null` when no match exists and is useful for asserting absence; `findBy` returns a promise and waits for an element to appear, making it appropriate for asynchronous UI updates.

Queries also have plural forms such as `getAllBy`, `queryAllBy`, and `findAllBy`. These are useful when multiple matching elements are expected. For example, `getAllByRole` returns an array and throws if no matching elements exist.

For accessibility-oriented tests, `getByRole` is usually the first query to consider. `getByLabelText` is useful for form controls associated with labels, while `getByText` can locate visible text. Test IDs such as `getByTestId` are a fallback when the desired element cannot be meaningfully identified through user-facing semantics.

A useful selection strategy is to start with the most user-facing query available and move toward less semantic selectors only when necessary. Query choice should also reflect timing: use synchronous queries for already-rendered content, absence queries for nonexistence, and asynchronous queries when the UI is expected to change.

Key points

Interview questions

What is the difference between `getBy`, `queryBy`, and `findBy`?

`getBy` performs a synchronous lookup and throws if no matching element exists. `queryBy` also performs a synchronous lookup but returns `null` when there is no match, so it is useful for testing absence. `findBy` is asynchronous and waits for a matching element to appear. The choice therefore depends on both whether the element should exist and whether its appearance is asynchronous.

Why is `getByRole` often preferred in React Testing Library?

`getByRole` queries an element through its accessible role, which reflects how users and assistive technologies understand the UI. It can also use an accessible name to distinguish elements such as buttons with similar roles. This makes tests less dependent on CSS classes or component implementation details. It can also reveal accessibility problems when an expected role or name is missing.

When should you use `queryBy`?

Use `queryBy` when the expected result is that an element is not present. Unlike `getBy`, it does not throw when the element is missing. For example, after rendering a component without an error message, `queryByRole('alert')` can be checked against `null` or with a matcher such as `not.toBeInTheDocument()`. It is generally not the first choice for finding content that should exist.

How would you test content that appears after an asynchronous update?

I would normally use a `findBy` query when the expected element should eventually appear. For example, `await screen.findByRole('status', { name: /loaded/i })` waits for the matching element. This keeps the test focused on the user-visible result rather than manually coordinating timing. If the behavior requires waiting for something other than finding an element, `waitFor` may be more appropriate.

What should you do if an element cannot be selected naturally with an accessible query?

First, I would check whether the markup can be improved so the element has meaningful accessible semantics. If a user-facing query genuinely does not fit the element, a test ID can be used as a fallback. The important point is not to introduce test IDs merely because they are convenient when a role, label, or text query would better represent the user interaction. This keeps the test aligned with observable behavior.