Contents

Engineering Craft › Testing

Testing Library Philosophy

Testing UI the way users use it, by role and text rather than internals.

Also known as: Testing Library, React Testing Library, user-centric testing, Testing Library guiding principle

Testing Library is a family of UI testing tools (for React, Vue, Angular and plain DOM) built on one idea: the more your tests resemble how users use your software, the more confidence they give you.

Users don’t look for div.btn-primary:nth-child(2) or check component state. They find a button that says “Save” and click it. So tests should too.

Query by what the user perceives

In order of preference:

QueryFinds
getByRole("button", { name: /save/i })Elements by accessible role and name
getByLabelText("Email")Form fields by their label
getByText("Welcome back")Visible text
getByTestId("save-btn")Last resort, with an explicit data-testid
await userEvent.type(screen.getByLabelText(/email/i), "ana@example.com");
await userEvent.click(screen.getByRole("button", { name: /sign in/i }));
expect(await screen.findByText(/welcome/i)).toBeInTheDocument();

Why this is good for you

  • Refactor-proof. Renaming a CSS class or restructuring internals doesn’t break tests, because behavior didn’t change.
  • Accessibility for free. If getByRole can’t find your button, a screen reader probably can’t either.
  • Readable tests: they read like a description of the user’s steps.

What not to do

Don’t test internal state, hooks or method calls directly, and don’t use container.querySelector unless you must. findBy... queries wait for elements to appear; use them for async UI instead of arbitrary timeouts. See component testing.