React Forum
Blog & Guide Responses
Jan 15, 2023 · 04:00 AM

React Testing Library Intro - discussion (2023-01-15)

Started by Lena Fischer
externaltesting-librarytestingqueriesuser eventsevidencedebuggability

Testing Library's intro is the link I send when teams get stuck writing tests that mirror component structure instead of user intent. I'm curious how people apply it in apps that lean heavily on route contracts, stored derived state, and render-visible evidence (so tests can assert behavior without peeking into internals).

Read the docs

Do you test route behavior by asserting on UI evidence (data-*, status text), or do you reach into state contracts? How do you keep tests resilient when you have lots of derived keys (counts, visible ids, previews)? What are your rules for getByRole/findBy* vs asserting on async timing explicitly?

Comments (14)

Back to latest
Marisol Vega
Jan 18, 2023 · 04:22 PM

Asserting on evidence is the biggest shift.

If the UI renders data-freshness or a status lane, tests can be stable without reading internal state.

Dmitri Kline
Jan 29, 2023 · 05:19 AM

A tiny example that matches the "user intent" posture:

tsx
render(<SupportShell><Queue /></SupportShell>);
await userEvent.type(screen.getByRole('searchbox'), 'refund');
expect(screen.getByText(/refund/i)).toBeInTheDocument();
expect(screen.getByTestId('queue')).toHaveAttribute('data-status', 'open');

The attribute assertion is the evidence layer; the text assertion is the user layer.

Keira Santos
Feb 12, 2023 · 11:40 PM

Counterpoint: too much data-* can turn into testing-only API and drift from reality.

We try to keep evidence minimal and meaningful (lane/status/selection), not every variable in the app.

Lena Fischer
Feb 16, 2023 · 08:10 AM

Agree. The evidence layer should explain behavior, not mirror implementation.

If the evidence is only there for tests, it's probably the wrong evidence.

Camille Duarte
Mar 07, 2023 · 06:33 AM

We avoided timing assertions by making async status explicit in the UI.

If the UI renders pending|ok|error, tests can just wait for the status change.

Grace McCoy
Mar 26, 2023 · 07:02 PM

The intro doc also helped us stop snapshotting huge trees.

Snapshots are fine when the output is intentional, but most of our snapshots were just noise.

Jasper Nguyen
Apr 18, 2023 · 12:55 PM

For derived keys, we treat them as part of the UI contract.

If a derived key affects a badge/count, we assert on the badge/count rather than the key itself.

Owen Price
May 11, 2023 · 03:14 AM

I still use findBy* when I need to wait for something real (like content appearing after a fetch).

But I avoid sleeping/timeout assertions as much as possible.

Nina Kapoor
Jun 24, 2023 · 08:21 PM

One trick: render the current route posture in a visually-hidden element.

Then tests can query it like normal content without relying on classnames.

Benji Rios
Aug 09, 2023 · 07:33 AM

A misunderstanding I see: people treat getByText as the default for everything.

Roles are better when the UI is accessible, and they make tests more resilient.

Amina Farouk
Oct 13, 2023 · 10:05 PM

Docs tie-in: the repo's emphasis on evidence is basically a testing strategy.

Related: Testing and Debugging and Performance and Rendering (Best Practices).

Theo Bennett
Jan 18, 2024 · 03:40 AM

Counterpoint: sometimes tests *should* reach into a contract (like a vault) if it's explicitly part of the app architecture.

We do it rarely, but for some invariants it was the cleanest assertion.

Marisol Vega
Jan 22, 2024 · 07:18 PM

I think that's fine if it's truly a contract and not an implementation detail.

But I still like having a UI evidence line so the same invariant is visible to humans too.

Salma Qureshi
May 20, 2024 · 10:10 AM

If your tests are brittle, it's often because the UI doesn't expose enough intent.

The fix might be better evidence, not more mocks.

Tomas Rivera
Oct 02, 2024 · 04:55 PM

Playwright vs RTL: we do RTL for component-level route posture and Playwright for full route flows.

But both benefit from the same thing: observable state in the UI.

Evan Brooks
Jul 11, 2025 · 04:44 AM

The intro doc is still the best antidote to "test the implementation" habits.

If you can phrase the assertion like a user expectation, it usually survives refactors.