This rule raises an issue when one of the Testing Library getBy*, getAllBy*, queryBy*, or queryAllBy* queries does not match an assertion that expects an element to be present or absent.

Why is this an issue?

Testing Library queries have different failure behavior. getBy* and getAllBy* throw when no element matches, while queryBy* returns null and queryAllBy* returns an empty array. A presence assertion should use a throwing query, so a failed test includes Testing Library’s diagnostic output. An absence assertion needs a non-throwing query so the assertion can observe the missing result.

Use getBy* or getAllBy* to assert that an element is present, and queryBy* or queryAllBy* to assert that it is absent. The rule reports only direct queries on an imported Testing Library screen object; custom queries and async utilities are outside its scope.

Code examples

Noncompliant code example

import { screen } from '@testing-library/react';

test('shows a dialog', () => {
  expect(screen.queryByRole('dialog')).toBeInTheDocument(); // Noncompliant: A presence assertion should use a "getBy-family" query so a missing element produces Testing Library diagnostics
});

Compliant solution

import { screen } from '@testing-library/react';

test('shows a dialog', () => {
  expect(screen.getByRole('dialog')).toBeInTheDocument();
});

Noncompliant code example

import { screen } from '@testing-library/react';

test('hides the dialog', () => {
  expect(screen.getByRole('dialog')).not.toBeInTheDocument(); // Noncompliant: An absence assertion should use a "queryBy-family" so it can observe a missing element
});

Compliant solution

import { screen } from '@testing-library/react';

test('hides the dialog', () => {
  expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
});

Resources

Documentation