← Back

Test Generator

This skill generates either Vitest unit tests for a specified file or Playwright E2E tests for a user flow. It analyzes existing code and conventions to create relevant test cases.

What it does

Generates software tests. For a given file path, it produces Vitest unit tests, analyzing exports, dependencies, and existing test patterns to ensure coverage. If invoked with e2e and a flow description, it generates Playwright end-to-end tests, identifying critical user flows and application structure.

When to use it

Use this skill when you need to quickly add unit tests to new or existing files, or to create comprehensive E2E tests for user flows in your application. It helps ensure code quality and verifies application behavior across various scenarios.

How to set it up

First, copy this skill's definition to .claude/skills/test-gen/SKILL.md in your repository. To generate Vitest unit tests for a file, invoke it with /test-gen [file-path]. For example, /test-gen src/utils/math.ts. To generate Playwright E2E tests for a user flow, use /test-gen e2e [flow description]. For instance, /test-gen e2e login flow.

The content

Test Generator

Generate tests for the given target.

Mode selection: If $0 is the literal token e2e, skip to the E2E Mode (Playwright) section at the bottom. Otherwise generate Vitest unit tests for the file per Steps 1–7 below.

Target: $ARGUMENTS Test framework: !cat package.json 2>/dev/null | grep -o '"vitest"' | head -1 || echo "vitest not found" Existing tests: !find src -name "*.test.ts" -o -name "*.test.tsx" -o -name "*.spec.ts" -o -name "*.spec.tsx" 2>/dev/null | head -10 || echo "none found"

Step 1: Analyze the Target File

Read $ARGUMENTS and extract:

  • All exported functions, classes, components, and types
  • Dependencies and imports (what needs mocking)
  • Side effects (API calls, database queries, file system access)
  • Input parameter types and return types

Step 2: Check for Existing Tests

Search for existing test files:

  • <filename>.test.ts / <filename>.test.tsx
  • <filename>.spec.ts / <filename>.spec.tsx
  • __tests__/<filename>.ts

If tests exist, read them and only add missing coverage. Do NOT duplicate existing test cases.

Step 3: Identify Test Cases

For each export, determine:

CategoryWhat to test
Happy pathNormal input produces expected output
Edge casesEmpty input, null/undefined, boundary values
Error pathsInvalid input, thrown errors, rejected promises
AsyncPromise resolution/rejection, timeout behavior
DependenciesMock external calls (API, DB, third-party libs)

Step 4: Follow Existing Conventions

If existing test files were found in Step 2, match their:

  • Import style (import { describe } from 'vitest' vs global)
  • Mock patterns (vi.mock, vi.fn, vi.spyOn)
  • File naming convention (.test.ts vs .spec.ts)
  • Describe/it block structure
  • Assertion style (expect().toBe(), expect().toEqual())

If no existing tests, use this default structure:

import { describe, it, expect, vi, beforeEach } from 'vitest';

Step 5: Generate Tests

Write the test file next to the source file (e.g., src/utils/calc.ts -> src/utils/calc.test.ts).

Rules:

  • One describe block per exported function/component
  • Descriptive test names: it('returns empty array when input is empty')
  • Arrange-Act-Assert pattern in each test
  • Mock external dependencies, never call real APIs/DB
  • Test the public interface, not implementation details
  • For React components: use @testing-library/react if available, otherwise test logic only

Step 6: Verify

Run the generated tests:

npx vitest run <test-file-path> --reporter=verbose

If tests fail:

  • Read the error output
  • Fix the test (not the source code)
  • Re-run until all pass

Step 7: Summary

Output:

  • Number of test cases generated
  • Coverage areas: happy path, edge cases, error paths
  • Any exports that were NOT tested (and why)
  • Test run result: PASS / FAIL

E2E Mode (Playwright)

Invoked as /test-gen e2e [flow description]. The remaining arguments after e2e describe the user flow to test (e.g. /test-gen e2e login flow). If no flow is given, generate tests for all critical paths (priority below).

E2E Step 1: Understand the Application

Identify:

  • Routing setup (Next app/ routes or react-router config)
  • Authentication flow (login page, auth guards)
  • Main user-facing pages, form components and their validation
  • API calls made during user flows
cat package.json | grep -o '"@playwright/test"' || echo "Playwright not installed"
ls playwright.config.* 2>/dev/null || echo "No Playwright config"
ls e2e/ tests/e2e/ tests/ 2>/dev/null | head -20

If Playwright is not installed:

npm install -D @playwright/test && npx playwright install chromium

E2E Step 2: Identify Critical User Flows

If no specific flow requested, prioritize:

  1. Authentication — sign up, login, logout, password reset
  2. Core CRUD — create, read, update, delete main entities
  3. Navigation — landing page → key features → back
  4. Error states — invalid form submission, 404 pages, unauthorized access
  5. Payment/checkout — if applicable

E2E Step 3: Analyze Page Structure

For each page: read the component file, identify interactive elements, find data-testid attributes or accessible roles, trace triggered API calls, identify loading/success/error states.

E2E Step 4: Generate Tests

Create test files in the project's E2E directory (usually e2e/ or tests/e2e/). Follow Playwright best practices:

  • Prefer accessible selectors: page.getByRole(), page.getByText(), page.getByTestId()
  • page.waitForURL() for navigation, expect(page).toHaveURL() for route verification
  • await expect(locator).toBeVisible() over waitForSelector
  • Group related tests in test.describe() blocks
  • test.beforeEach() for common setup (login, navigation)
  • If a storageState auth fixture exists, use it for authenticated flows; otherwise log in via UI in beforeEach

Each test must assert meaningfully: URL changed, expected content visible, form feedback shown, data persists after reload where applicable.

E2E Step 5: Verify

npx playwright test <test-file> --reporter=list 2>&1

If tests fail: read the error output, fix the test (selectors, timing, assertions), re-run until passing.

E2E Step 6: Summary

Output:

  • Files generated and flows covered
  • Selector breakdown (roles / test IDs / text)
  • Test run result: PASS / FAIL / SKIP with reasons
  • Missing coverage and recommended data-testid additions

Served straight from the framework this site runs on. This page always shows the current version.

Want something like this for you?

It starts with a conversation: 30 minutes, no strings attached.