Technology handbook
React Testing Library — User-Centered UI Tests
User-centered React tests built around accessible queries, interactions and observable outcomes.
- Topics
- 17
- Sections
- 4
Queries
Queries by role
Find buttons, headings, links and fields the way assistive technology finds them.
- Query by the element's semantic role and accessible name.
- Use role options to distinguish state such as checked or selected.
- Treat missing semantics as a possible accessibility defect.
Labels and accessible names
Use labels and names to make form tests both robust and accessibility-aware.
- Associate form labels with their controls.
- Distinguish visible text from the computed accessible name.
- Test named controls instead of placeholder-only identification.
getByLabelText
Find form controls through their accessible labels and catch missing label regressions.
- Query the control through its associated label text.
- Use precise matching when several labels are similar.
- Check that the returned element is the intended editable control.
getByText and getByTestId
Use visible text first and reserve test IDs for stable semantic gaps.
- Use getByText for visible non-interactive content.
- Prefer semantic queries when a control has a role and name.
- Reserve test IDs for elements without a useful semantic contract.
within
Scope a query to a card, dialog or repeated region before finding its controls.
- Select the containing card, region or dialog first.
- Use within(container) for its repeated labels and controls.
- Avoid positional selectors when semantic scoping identifies the target.
Interactions
userEvent interactions
Model realistic typing, clicking, tabbing and keyboard behavior instead of firing internals.
- Create a userEvent session with setup.
- Await interactions that dispatch asynchronous user-event sequences.
- Assert the resulting UI rather than manually firing internal handlers.
Testing forms
Assert validation and submitted outcomes from the user’s perspective.
- Find inputs by label and submit through the form's visible control.
- Exercise valid input and a meaningful invalid case.
- Assert displayed errors or the submitted domain payload.
userEvent keyboard flows
Test typing, tab order, focus, keyboard shortcuts and selection like a real user.
- Tab through controls and check the resulting focus.
- Exercise Enter, Space or Escape where the interaction requires them.
- Test keyboard behavior without relying solely on pointer clicks.
Dialogs and portals
Test modal semantics and portal-rendered content through accessible roles.
- Find modal content through its dialog role and accessible name.
- Query the document when portal content is outside the render container.
- Verify dismissal and focus restoration after closing.
Form validation
Assert field errors, submit state and successful outcomes from observable behavior.
- Check when validation appears and how it is associated with fields.
- Verify disabled or pending submission states.
- Correct invalid values and assert the successful recovery path.
Async behavior
Async UI
Wait for loading, success and error states with findBy and waitFor when the UI changes over time.
- Use findBy when an element should appear asynchronously.
- Check loading, successful and failed outcomes explicitly.
- Prefer observable state changes over arbitrary time delays.
findBy and waitFor
Wait for asynchronous UI changes with the correct retrying query or assertion.
- findBy combines an element query with asynchronous retries.
- Put a throwing assertion inside waitFor.
- Keep side effects outside waitFor because its callback can repeat.
waitForElementToBeRemoved
Verify that a loading or temporary element disappears after work completes.
- Verify the element exists before waiting for its removal.
- Pass the element or a callback that finds it.
- Distinguish actual removal from content that merely becomes hidden.
MSW and network boundaries
Mock HTTP at the network boundary so components exercise realistic loading and error paths.
- Intercept HTTP responses instead of replacing component internals.
- Simulate pending, successful and failed network outcomes.
- Reset handlers between scenarios to prevent response leakage.
Test design
Avoiding implementation details
Prefer visible behavior and accessible contracts over component state and private methods.
- Test behavior that a user or external caller can observe.
- Avoid reading private hook state or component instances.
- Keep tests valid when implementation changes preserve behavior.
Accessibility assertions
Check roles, names, states and keyboard behavior as part of normal component tests.
- Assert accessible names, descriptions and exposed states.
- Include focus and keyboard behavior in interactive flows.
- Combine automated checks with review of meaningful semantics.
Cleanup and isolation
Reset the DOM and mocks between tests so one render cannot affect another.
- Unmount rendered trees and clear test-specific mocks.
- Reset timers and external stores used by the component.
- Wait for owned asynchronous work instead of leaking it into another test.