Rendering and Querying Elements
In this page:
getBy vs. queryBy vs. findBy
getBy* throws an error immediately if no matching element exists, making it ideal for asserting something IS present. queryBy* returns null instead of throwing, making it the right choice for asserting something is ABSENT. findBy* returns a Promise and waits, ideal for elements that appear after an async action.
Note: A simple mental model: getBy for 'this should exist right now', queryBy for 'this should NOT exist', findBy for 'this will exist soon'.
Warning: Using getBy* to check something is absent throws an unhelpful error instead of a clean assertion failure — use queryBy* + toBeNull() or not.toBeInTheDocument() instead.
Example: getBy vs. queryBy vs. findBy
// Run in your local React project (npm install required)
import { render, screen } from '@testing-library/react';
import Alert from './Alert';
test('alert is not shown initially', () => {
render(<Alert show={false} />);
expect(screen.queryByText('Warning!')).not.toBeInTheDocument();
});
⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.
Waiting for Async Content with findBy
When content appears after an asynchronous action (like a fetch resolving), findBy* queries return a Promise that repeatedly checks for the element until it appears or a timeout is reached, avoiding the need for manual waiting or arbitrary setTimeout calls in tests.
Note: Always await a findBy* query — forgetting the await means the test moves on before the element has actually appeared.
Warning: findBy* has a default timeout (usually 1000ms) — a genuinely slow-loading element might need an explicit longer timeout passed as an option.
Example: Waiting for Async Content with findBy
// Run in your local React project (npm install required)
import { render, screen } from '@testing-library/react';
import UserProfile from './UserProfile';
test('shows user name after loading', async () => {
render(<UserProfile userId={1} />);
const name = await screen.findByText('Asha');
expect(name).toBeInTheDocument();
});
⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.
The Recommended Query Priority
Testing Library recommends a priority order for which query to reach for first: getByRole is preferred (it reflects real accessibility semantics), then getByLabelText for form fields, then getByText for general content, with test-ID-based queries as a last resort when nothing else fits.
Note: Following this priority order tends to naturally push your components toward better accessibility, since you're forced to think about roles and labels.
Warning: Reaching straight for getByTestId as a default habit skips the accessibility benefits the other queries encourage, and misses catching accessibility issues your tests could otherwise reveal.
Example: The Recommended Query Priority
// Run in your local React project (npm install required)
// Priority order (most to least preferred):
screen.getByRole('button', { name: 'Save' }); // 1st choice
screen.getByLabelText('Email address'); // 2nd choice
screen.getByText('Welcome back'); // 3rd choice
screen.getByTestId('save-button'); // last resort
- Using getByText for elements identified better by role, missing accessibility semantics the test could otherwise verify.
- Not knowing the difference between getBy, queryBy, and findBy — each behaves differently for missing or async elements.
- Overusing container.querySelector, bypassing Testing Library's user-centric query system entirely.
- getBy* queries throw if zero or multiple matches are found — use for elements expected to exist right now.
- queryBy* returns null instead of throwing — use to assert something does NOT exist.
- findBy* returns a Promise, waiting for an element to appear — use for content that shows up asynchronously.
- Query priority (recommended order): getByRole, getByLabelText, getByText, then more implementation-specific options.
Requires npm install @testing-library/react — runs in a Node test environment, not this browser sandbox.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: