Q43 of 48 · Cypress

What testability requirements would you push for as part of code review?

CypressSeniorcypresstestabilitycode-reviewsenior

Short answer

Short answer: Stable test attributes (`data-test`) on every interactive element, deterministic IDs (no random UUIDs in DOM), no hard-coded `Date.now()` for displayed values, hooks for resetting state in test environments, and avoidance of CSS-only behaviour that tests can't observe.

Detail

Testability isn't a QA concern handed off to developers — it's an architectural property the whole team owns. As a Cypress lead reviewing PRs, the testability changes I push for:

1. data-test attributes on every interactive element. Buttons, links, form fields, important containers. Naming convention: data-test=feature-action (kebab case, scoped). Lint or pre-commit can warn about new buttons without one.

2. Deterministic test IDs in lists. data-test=cart-row-{itemId} rather than data-test=cart-row for multi-item lists. Tests can address specific rows without .eq(N).

3. No live time in DOM strings. "2 hours ago", "Today at 3pm" — these break tests every hour. Either use stable format ("2026-05-10 13:00") or expose the timestamp as data-timestamp for tests to read.

4. Stable IDs in URLs and attributes. A new UUID per page load means the URL after click is unpredictable. Prefer stable slugs / paths where possible; if UUIDs are unavoidable, expose them as data-id attributes.

5. Test-mode hooks. A window.__test__ namespace (only populated in non-prod) where the app exposes utilities — clear local cache, dispatch a synthetic event, fast-forward animations. Don't bake test-only logic into prod paths.

6. Animations toggleable for tests. A CSS class .no-animations on html that the test environment sets, disabling transition and animation globally. Removes a major source of flake.

7. Avoid CSS-only state. A "selected" state expressed only as background-color is hard to assert on (colours change with themes). Add a class or attribute (aria-selected).

8. Network requests over local-only state. A computed value rendered from Math.random() on each render is hostile to tests. If it's user-meaningful, derive it from server state. If it's not, hide it.

9. ARIA roles and accessible names. getByRole-friendly markup (a meaningful <button>, a labelled <input>) helps both tests and users. A11y and testability are usually aligned.

10. Idempotent endpoints with explicit keys. Test setup often hits the API to seed state; idempotent endpoints with caller-supplied keys (POST /orders with Idempotency-Key header) make seed scripts safer to retry.

The cultural piece: framing these as shared engineering quality, not "QA's wishlist". A test-friendly app is also easier to debug, document, and maintain.

// WHAT INTERVIEWERS LOOK FOR

A specific list of architectural asks (test attributes, no live time, animations toggle, test-mode hooks). Bonus for framing as shared eng quality and noting the a11y alignment.

// COMMON PITFALL

Listing only `data-test` attributes — that's the table-stakes ask. Senior reviewers push for the deeper changes (no live time, animation toggles, test-mode hooks).