React testing skill

Test React components with RTL and Jest/Vitest.

by HoangNguyen0403·MIT license·★ 569 Stars on the repo·GitHub ↗

Use now

Files of React testing

HoangNguyen0403/develop1 file shown
SKILL.md
Show the full text77 lines

React Testing

Priority: P1 (HIGH)

Core Philosophy

  • Test User Behavior, Not Implementation Mechanics: Tests should verify that the application works for end users, rather than checking how components are implemented internally.
  • Resistance to Refactoring: Refactoring component internal state, props, or hooks must never break passing tests as long as the user-visible behavior remains unchanged.

Core Rule Anchors (Four Pillars Enforcement)

  • [WEB-TEST-01] Tripartite Naming & AAA Cadence: Test names must follow Method_Scenario_ExpectedBehavior and adhere strictly to Arrange-Act-Assert. Example: SubmitOrder_WhenCreditLimitExceeded_DisplaysBlockedBanner.
  • [WEB-TEST-02] Accessible Roles & UserEvent: Always use userEvent.setup() for user interactions (await user.click(...)) and query elements via accessible roles (getByRole, findByLabelText). Avoid fireEvent and ban arbitrary CSS / DOM hierarchy selectors.
  • [WEB-TEST-03] Ban on Component State & Prop Inspection: Never inspect internal component state or props directly. Never write trivial echo assertions (expect(true).toBe(true)). Assert on visible user outcomes and DOM state changes.
  • [WEB-TEST-04] Mock Service Worker (MSW) Network Mocking: Intercept network requests at the HTTP boundary via MSW rather than mocking internal Apollo Client hooks (useQuery) or Redux dispatchers. Tests must verify true end-to-end component data flow.
  • [WEB-TEST-05] Bug-First Regression Lock: Every PR resolving a bug ticket or with title fix(...) must introduce a test reproducing the defect prior to the fix.

Implementation Guidelines

  • Standards: Use React Testing Library (RTL) with Vitest or Jest. Follow Arrange-Act-Assert (AAA) pattern ([WEB-TEST-01]).
  • User-Centric Selection: Prioritize accessible queries: getByRole, findByLabelText, getByText. Treat data-testid only as an explicit fallback for complex UI elements, and strictly ban CSS class or DOM hierarchy selectors ([WEB-TEST-02]).
  • Behavioral Assertions: Test user workflows using userEvent.setup() (e.g., const user = userEvent.setup(); await user.click(...)) rather than firing raw synthetic DOM events with fireEvent ([WEB-TEST-02]).
  • Network Boundary Mocking (MSW): Mock API network requests at the HTTP layer using Mock Service Worker (MSW) instead of mocking Apollo Client hooks (useQuery, useMutation) or Redux dispatchers. This validates end-to-end component data flow without leaking mock internals. Never call real APIs in unit/integration tests ([WEB-TEST-04]).
  • Asynchrony: Use await screen.findBy* for elements rendered after asynchronous actions. Use waitFor(() => ...) only for complex non-element updates or assertion retries.
  • Architecture: Test behavior, not implementation. Never inspect component internal state or props ([WEB-TEST-03]).
  • Mocks: Mock expensive third-party libraries (e.g., framer-motion, react-router) or heavy assets at the boundary to speed up tests.
  • Visuals: Use Snapshot testing sparingly for stable, small UI components. Banish large snapshot tests of dynamic pages. Manual a11y checks with jest-axe.

Anti-Patterns & Banned Smells

  • [WEB-TEST-01] Vague test names: Banish non-descriptive names; adhere to Method_Scenario_ExpectedBehavior.
  • [WEB-TEST-02] No Synthetic Events or CSS Selectors: Avoid fireEvent; always use userEvent.setup(). Ban querying by CSS classes or DOM hierarchy.
  • [WEB-TEST-03] No Testing Implementation Details: Never inspect or assert on component internal state or props directly.
  • [WEB-TEST-04] No Hook / Dispatcher Mocking: Do not mock Apollo Client hooks or Redux dispatchers directly; intercept network requests via MSW handlers.
  • [WEB-TEST-05] No Bug Fix Without Reproduction: Ban bug fix PRs without defect reproduction tests.
  • No Large Dynamic Snapshots: Ban snapshot tests of dynamic pages, lists, or complex containers.
  • No Shallow Rendering: Render the full component tree with required providers.
  • No Wait-for-Find: Prefer await screen.findBy* over waitFor(() => screen.getBy*).

References

See references/REFERENCE.md for MSW API mocking, Context testing, form testing, and React Router patterns.

Code

test('submits form', async () => {
  const user = userEvent.setup();
  render(<LoginForm />);

  await user.type(screen.getByLabelText(/email/i), '[email protected]');
  await user.click(screen.getByRole('button', { name: /login/i }));

  expect(await screen.findByText(/welcome/i)).toBeInTheDocument();
});

Canonical response anchors

When this skill applies, preserve the following domain terminology or equivalent concrete examples in the answer when relevant:

  • findByText
  • getByRole
1---
2name: react-testing
3description: Test React components with RTL and Jest/Vitest. Use when writing React component tests with React Testing Library, Jest, or Vitest.
4metadata:
5 triggers:
6 files:
7 - '**/*.test.tsx'
8 - '**/*.spec.tsx'
9 keywords:
10 - render
11 - screen
12 - userEvent
13 - expect
14---
15# React Testing
16 
17## **Priority: P1 (HIGH)**
18 
19## Core Philosophy
20 
21- **Test User Behavior, Not Implementation Mechanics**: Tests should verify that the application works for end users, rather than checking how components are implemented internally.
22- **Resistance to Refactoring**: Refactoring component internal state, props, or hooks must never break passing tests as long as the user-visible behavior remains unchanged.
23 
24## Core Rule Anchors (Four Pillars Enforcement)
25 
26- **`[WEB-TEST-01]` Tripartite Naming & AAA Cadence**: Test names must follow `Method_Scenario_ExpectedBehavior` and adhere strictly to Arrange-Act-Assert. Example: `SubmitOrder_WhenCreditLimitExceeded_DisplaysBlockedBanner`.
27- **`[WEB-TEST-02]` Accessible Roles & UserEvent**: Always use `userEvent.setup()` for user interactions (`await user.click(...)`) and query elements via accessible roles (`getByRole`, `findByLabelText`). Avoid `fireEvent` and ban arbitrary CSS / DOM hierarchy selectors.
28- **`[WEB-TEST-03]` Ban on Component State & Prop Inspection**: Never inspect internal component state or props directly. Never write trivial echo assertions (`expect(true).toBe(true)`). Assert on visible user outcomes and DOM state changes.
29- **`[WEB-TEST-04]` Mock Service Worker (MSW) Network Mocking**: Intercept network requests at the HTTP boundary via MSW rather than mocking internal Apollo Client hooks (`useQuery`) or Redux dispatchers. Tests must verify true end-to-end component data flow.
30- **`[WEB-TEST-05]` Bug-First Regression Lock**: Every PR resolving a bug ticket or with title `fix(...)` must introduce a test reproducing the defect prior to the fix.
31 
32## Implementation Guidelines
33 
34- **Standards**: Use **React Testing Library (RTL)** with **Vitest or Jest**. Follow **Arrange-Act-Assert (AAA)** pattern (`[WEB-TEST-01]`).
35- **User-Centric Selection**: Prioritize accessible queries: **`getByRole`**, **`findByLabelText`**, **`getByText`**. Treat `data-testid` only as an explicit fallback for complex UI elements, and strictly ban CSS class or DOM hierarchy selectors (`[WEB-TEST-02]`).
36- **Behavioral Assertions**: Test user workflows using **`userEvent.setup()`** (e.g., `const user = userEvent.setup(); await user.click(...)`) rather than firing raw synthetic DOM events with `fireEvent` (`[WEB-TEST-02]`).
37- **Network Boundary Mocking (MSW)**: Mock API network requests at the HTTP layer using **Mock Service Worker (MSW)** instead of mocking Apollo Client hooks (`useQuery`, `useMutation`) or Redux dispatchers. This validates end-to-end component data flow without leaking mock internals. **Never call real APIs** in unit/integration tests (`[WEB-TEST-04]`).
38- **Asynchrony**: Use **`await screen.findBy*`** for elements rendered after asynchronous actions. Use **`waitFor(() => ...)`** only for complex non-element updates or assertion retries.
39- **Architecture**: **Test behavior**, not implementation. Never inspect component internal `state` or `props` (`[WEB-TEST-03]`).
40- **Mocks**: Mock expensive third-party libraries (e.g., `framer-motion`, `react-router`) or heavy assets at the boundary to speed up tests.
41- **Visuals**: Use **Snapshot testing** sparingly for stable, small UI components. Banish large snapshot tests of dynamic pages. **Manual a11y checks** with `jest-axe`.
42 
43## Anti-Patterns & Banned Smells
44 
45- **`[WEB-TEST-01]` Vague test names**: Banish non-descriptive names; adhere to `Method_Scenario_ExpectedBehavior`.
46- **`[WEB-TEST-02]` No Synthetic Events or CSS Selectors**: Avoid `fireEvent`; always use `userEvent.setup()`. Ban querying by CSS classes or DOM hierarchy.
47- **`[WEB-TEST-03]` No Testing Implementation Details**: Never inspect or assert on component internal `state` or `props` directly.
48- **`[WEB-TEST-04]` No Hook / Dispatcher Mocking**: Do not mock Apollo Client hooks or Redux dispatchers directly; intercept network requests via MSW handlers.
49- **`[WEB-TEST-05]` No Bug Fix Without Reproduction**: Ban bug fix PRs without defect reproduction tests.
50- **No Large Dynamic Snapshots**: Ban snapshot tests of dynamic pages, lists, or complex containers.
51- **No Shallow Rendering**: Render the full component tree with required providers.
52- **No Wait-for-Find**: Prefer `await screen.findBy*` over `waitFor(() => screen.getBy*)`.
53 
54## References
55 
56See [references/REFERENCE.md](references/REFERENCE.md) for MSW API mocking, Context testing, form testing, and React Router patterns.
57 
58## Code
59 
60```tsx
61test('submits form', async () => {
62 const user = userEvent.setup();
63 render(<LoginForm />);
64 
65 await user.type(screen.getByLabelText(/email/i), '[email protected]');
66 await user.click(screen.getByRole('button', { name: /login/i }));
67 
68 expect(await screen.findByText(/welcome/i)).toBeInTheDocument();
69});
70```
71 
72## Canonical response anchors
73 
74When this skill applies, preserve the following domain terminology or equivalent concrete examples in the answer when relevant:
75- findByText
76- getByRole
77 

Discussion

Alternatives

shadcn/uiManages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI, including chat interfaces. Provides project context, component docs, and usage examples. Applies when working with shadcn/ui, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for "shadcn init", "create an app with --preset", or "switch to --preset".Coding · MITADK Code ReferenceThis skill should be used when the user wants to "write agent code", build an agent with ADK", "add a tool", "create a callback", "define an agent", use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).Coding · Apache-2.0Visual editOpen and collaboratively edit a running local app in Design, with shared fallback previews and source handoff. Use when the user asks to inspect, share, or edit a real local app in Design.Coding · MITModsmithPatterns, cost review and ready templates for Claude Mods (Claude Code plugins whose behaviour is a function-hooks module). Adds what the built-in mod authoring does not: proven designs (fork-check-draw, tool + ledger, mode registry, artifact-backed state), prompt-cache and token-cost review, a vetting pass for someone else's mod, and rules for mods that compose. USE WHEN: build a mod, make a claude mod, mod templates, quiz me after each turn, assumptions tool / register_assumption, supervisor that checks the turn, next-steps check, mode selector / mode registry, effort by domain, model router that keeps the cache, prompt cache cost of a mod, what does this mod cost per turn, review or vet someone's mod before installing, mods that work together, Kanban artifact as shared project state. NOT FOR: classic shell-command hooks in settings.json (PreToolUse etc.), a plain skill or slash command, MCP server authoring, or looking up the hooks API itself (use the engine's plugin-authoring guidance and generated types).Coding · MIT