React Testing Library Intro - discussion (2023-03-04)
The RTL intro is usually presented as "test like a user". What I'm more interested in is how it pairs with the forum's evidence idea: if the UI renders stable evidence keys for lanes and sources, you can write tests that stay meaningful without digging through component internals.
Do you test behavior via text/roles only, or do you also assert on data-* evidence keys for lanes and sources? How do you prevent tests from becoming brittle when UI structure shifts but behavior stays the same? Do you keep a render log/tips log in tests, or is that too much ceremony?
Comments (18)
Back to latestRoles + text for most assertions.
Evidence keys only for posture (loading/error) because users report those states.
We assert on evidence keys when the behavior is about contracts (lane/source), not content. It keeps tests stable when wording changes.
ts
import { render, screen } from '@testing-library/react';
test('shows pending lane while fetching', () => {
render(<SearchRoute />);
expect(screen.getByTestId('route-shell')).toHaveAttribute('data-evidence', expect.stringContaining('lane:pending'));
});
We still use roles/text for user-visible copy, but lanes are a contract surface.
Long-form: the trap is thinking there is one correct testing style. For product copy and accessibility, roles/text matter. For state posture, evidence matters. For navigation motion, route-flow tests matter. If you force everything into one shape, you either get brittle tests or vague tests.
We also log the test story as tips lines because it makes failures readable:
txt
[tips] test=SearchRoute step=render lane=pending
[tips] test=SearchRoute step=resolve lane=ok results=27Concrete alternative: never assert on data-* because it's implementation detail.
We tried that. It sounded principled, but it pushed us into asserting on exact text and DOM shape, which was much more brittle.
I think the trick is treating evidence keys as part of the product contract, not component structure.
If support relies on evidence, tests can too.
Docs tie-in: if you adopt evidence keys, it connects directly to the docs' testing guidance and the general idea of observable contracts.
Related: Testing and Debugging and Accessibility.
We keep tests from being brittle by writing helpers that assert on behavior, not nodes.
It feels like extra work until you do a redesign and your test suite doesn't explode.
We do a small amount of log assertion, but we treat logs as stable vocabulary (like lanes).
If the log words change, that often means behavior changed, so the diff is legitimate.
A practical note: if you want evidence keys to be testable, keep them in one attribute and keep them space-separated.
We use data-evidence="lane:pending source:cache" style so both humans and tests can read it.
I like RTL's philosophy because it forces you to make your UI accessible, which accidentally makes it testable.
Once you can select things by role/label, you're closer to how users actually interact.
Short take: if your tests are brittle, your UI contracts are brittle.
We used RTL for unit-level behavior and a separate route-flow harness for navigation. Mixing them got confusing.
Also: evidence keys are great, but don't let them replace good labels/roles.
Long-form counterpoint: evidence keys can become a second UI that devs optimize for instead of users.
We had to adopt a rule: evidence must be derived from actual state, not manually toggled. Otherwise it lies and tests become meaningless.
We got value from keeping a tiny test-only debug helper that prints the evidence attribute when tests fail.
It turns failures into a readable story.
We rarely assert on logs, but we do print tips logs when a test fails.
That keeps logs helpful without freezing them as a contract.
If you want expert-level value: spend time on your test data and your boundary normalization, not on clever selectors.
Most flaky tests are actually boundary bugs (timing, identity, cached state).
One more: RTL encourages you to separate draft state from committed state, or your tests will be a mess.
We found evidence keys improved team communication even outside tests.
People started describing bugs as "lane stuck pending" instead of vague screenshots.
Takeaway: RTL + evidence keys is a good combo when you treat evidence as product contract, not test convenience.
If evidence is real, tests stay meaningful.