.agents/skills/testing-setup/SKILL.md
Guide for writing tests using the project's testing infrastructure. Use when writing tests, creating test files, or when the user asks about testing setup, test utilities, fixtures, or mocks.
npx skillsauth add FabioFiorita/tastik testing-setupInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Import test utilities from @/test-utils instead of @testing-library/react:
import { renderWithUser, screen } from "@/test-utils";
it("interacts with component", async () => {
const { user } = renderWithUser(<MyComponent />);
await user.click(screen.getByRole("button"));
expect(screen.getByText("Clicked")).toBeInTheDocument();
});
renderWithUser()Combines render() and userEvent.setup() automatically. Use this instead of the regular render from @testing-library/react.
import { renderWithUser, screen } from "@/test-utils";
it("handles user interaction", async () => {
const { user } = renderWithUser(<MyComponent />);
await user.click(screen.getByTestId("my-button"));
expect(await screen.findByText("Clicked")).toBeInTheDocument();
});
@/test-utils re-exports all utilities from @testing-library/react and userEvent, so you can import everything from one place.
src/__tests__/helpers/fixtures.ts)Use predefined test data to avoid duplication:
import { mockUser, mockList } from "@/__tests__/helpers/fixtures";
it("uses fixture data", () => {
expect(mockUser.email).toBe("[email protected]");
});
src/lib/helpers/mocks.ts)Use reusable mocks for common dependencies:
import { useTheme } from "next-themes";
import { mockNextThemes } from "@/lib/helpers/mocks";
import { renderWithUser, screen } from "@/test-utils";
const { mockSetTheme } = mockNextThemes();
it("calls setTheme when theme button is clicked", async () => {
function ThemeButton() {
const { setTheme } = useTheme();
return (
<button data-testid="theme-dark" type="button" onClick={() => setTheme("dark")}>
Dark
</button>
);
}
const { user } = renderWithUser(<ThemeButton />);
await user.click(screen.getByTestId("theme-dark"));
expect(mockSetTheme).toHaveBeenCalledWith("dark");
});
All tests must be organized within describe blocks:
describe("my-component", () => {
let asAlice: TestIdentity;
beforeEach(async () => {
// setup code
});
it("renders correctly", () => {
renderWithUser(<MyComponent />);
expect(screen.getByTestId("my-element")).toBeInTheDocument();
});
it("handles user interaction", async () => {
const { user } = renderWithUser(<MyComponent />);
await user.click(screen.getByTestId("my-button"));
expect(await screen.findByText("Clicked")).toBeInTheDocument();
});
});
renderWithUser - Automatically sets up userEvent for cleaner testsdata-testid - Use on interactive components and key UI elementsdescribe blocks - Every test file must have a parent describe blockfindBy* queries - For async content instead of waitFor + getBy*cleanup() - Automatic cleanup is handled globallyact() - React Testing Library handles this automaticallyuserEvent - Always use userEvent instead of fireEvent for interactionsasync/await - User interactions are asynchronousFor detailed information on specific testing patterns, see:
bun test - Run tests in watch modebun test:once - Run all tests oncebun test:ui - Open Vitest UIbun test:coverage - Generate coverage reportbun test:unit - Run only unit tests (not convex)bun test:convex - Run only convex backend testsbun test:debug - Debug modeCoverage thresholds are set to 70% for:
Run bun test:coverage to generate a coverage report.
The project includes automatic test setup (src/test-setup.ts):
Two test projects configured:
tools
Cloudflare Workers CLI for deploying, developing, and managing Workers, KV, R2, D1, Vectorize, Hyperdrive, Workers AI, Containers, Queues, Workflows, Pipelines, and Secrets Store. Load before running wrangler commands to ensure correct syntax and best practices.
development
Reviews and authors Cloudflare Workers code against production best practices. Load when writing new Workers, reviewing Worker code, configuring wrangler.jsonc, or checking for common Workers anti-patterns (streaming, floating promises, global state, secrets, bindings, observability). Biases towards retrieval from Cloudflare docs over pre-trained knowledge.
tools
Analyzes web performance using Chrome DevTools MCP. Measures Core Web Vitals (FCP, LCP, TBT, CLS, Speed Index), identifies render-blocking resources, network dependency chains, layout shifts, caching issues, and accessibility gaps. Use when asked to audit, profile, debug, or optimize page load performance, Lighthouse scores, or site speed.
development
React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.