Which query should I use?
Priority
Based on the Guiding Principles, your test should resemble how users interact with your code (component, page, etc.) as much as possible. With this in mind, we recommend this order of priority:
- Queries Accessible to Everyone queries that reflect the experience of
visual/mouse users as well as those that use assistive technology
getByRole
: This can be used to query every element that is exposed in the accessibility tree. With thename
option you can filter the returned elements by their accessible name. This should be your top preference for just about everything. There's not much you can't get with this (if you can't, it's possible your UI is inaccessible). Most often, this will be used with thename
option like so:getByRole('button', {name: /submit/i})
. Check the list of roles.getByLabelText
: Only really good for form fields, but this is the number one method a user finds those elements, so it should be your top preference.getByPlaceholderText
: A placeholder is not a substitute for a label. But if that's all you have, then it's better than alternatives.getByText
: Not useful for forms, but this is the number 1 method a user finds most non-interactive elements (like divs and spans).getByDisplayValue
: The current value of a form element can be useful when navigating a page with filled-in values.
- Semantic Queries HTML5 and ARIA compliant selectors. Note that the user
experience of interacting with these attributes varies greatly across
browsers and assistive technology.
getByAltText
: If your element is one which supportsalt
text (img
,area
, andinput
), then you can use this to find that element.getByTitle
: The title attribute is not consistently read by screenreaders, and is not visible by default for sighted users
- Test IDs
getByTestId
: The user cannot see (or hear) these, so this is only recommended for cases where you can't match by role or text or it doesn't make sense (e.g. the text is dynamic).
Manual Queries
On top of the queries provided by the testing library, you can use the regular
querySelector
DOM API
to query elements. Note that using this as an escape hatch to query by class or
id is a bad practice because users can't see or identify these attributes. Use a
testid if you have to.
// @testing-library/react
const { container } = render(<MyComponent />)
const foo = container.querySelector('[data-foo="bar"]')
Playground
If you want to get more familiar with these queries, you can try them out on testing-playground.com. Testing Playground is an interactive sandbox where you can run different queries against your own html, and get visual feedback matching the rules mentioned above.