# testing-react > Use when testing React components with Vitest and React Testing Library - Author: Dario Farzati - Repository: mostlyhumanagency/claude-plugin-coding-react - Version: 20260209222058 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-10 - Source: https://github.com/mostlyhumanagency/claude-plugin-coding-react - Web: https://mule.run/skillshub/@@mostlyhumanagency/claude-plugin-coding-react~testing-react:20260209222058 --- --- name: testing-react description: Use when testing React components with Vitest and React Testing Library --- # Testing React Components Test React components by simulating user behavior with Vitest and React Testing Library (RTL). Focus on what users see and do, not implementation details. ## Overview This skill helps you write component tests using: - **Vitest** — Fast, Vite-native test runner with Jest-compatible API - **React Testing Library** — Query and interact with components like a user would - **userEvent** — Simulate realistic user interactions - **jsdom** — Browser environment for Node.js tests Tests render components, query elements by role/label/text, simulate user interactions, and assert on visible changes. ## When to Use - Testing component rendering and display logic - Testing user interactions (clicks, typing, form submissions) - Testing async behavior (data fetching, Suspense) - Testing form actions and state updates - Setting up a new React project's test infrastructure ## Setup Install dependencies: ```bash npm install -D vitest @testing-library/react @testing-library/jest-dom @testing-library/user-event jsdom ``` Create `vitest.config.ts`: ```typescript import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react"; export default defineConfig({ plugins: [react()], test: { environment: "jsdom", setupFiles: "./src/test-setup.ts", }, }); ``` Create `src/test-setup.ts`: ```typescript import "@testing-library/jest-dom/vitest"; import { cleanup } from "@testing-library/react"; import { afterEach } from "vitest"; afterEach(() => { cleanup(); }); ``` ## Core Patterns ### Basic Component Test ```tsx import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { expect, test } from "vitest"; test("shows greeting after clicking button", async () => { const user = userEvent.setup(); render(); await user.click(screen.getByRole("button", { name: "Say hello" })); expect(screen.getByText("Hello, Alice!")).toBeInTheDocument(); }); ``` ### Form Submission Test ```tsx test("submits form and shows result", async () => { const user = userEvent.setup(); render(); await user.type(screen.getByLabelText("Quantity"), "2"); await user.click(screen.getByRole("button", { name: "Add to Cart" })); expect(await screen.findByText("Added to cart!")).toBeInTheDocument(); }); ``` ## Quick Reference ### Query Priority | Priority | Query | Use When | |----------|-------|----------| | 1st | `getByRole` | Any element with ARIA role (buttons, inputs, headings) | | 2nd | `getByLabelText` | Form fields with labels | | 3rd | `getByPlaceholderText` | Inputs with placeholder | | 4th | `getByText` | Non-interactive text content | | 5th | `getByTestId` | Last resort — no semantic query works | ### Query Variants | Variant | Behavior | |---------|----------| | `getBy*` | Throws if not found; synchronous | | `queryBy*` | Returns `null` if not found; for asserting absence | | `findBy*` | Async; waits for element to appear | | `*AllBy*` | Returns array of matches | ## Common Mistakes - **Using `act` from wrong import** — Import from `react`, not `react-dom/test-utils` - **Using `getBy*` for async content** — Use `findBy*` or `waitFor` instead - **Testing implementation details** — Test user-visible behavior, not state/props - **Not calling `userEvent.setup()`** — Always setup before interactions - **Using `fireEvent`** — Prefer `userEvent` for realistic event sequences See [patterns.md](./patterns.md) for comprehensive examples and advanced patterns.