option
HomeHome Skill Browser Automation frontend-testing-best-practices

frontend-testing-best-practices

sergiodxa/agent-skills sergiodxa/agent-skills

Testing best practices for the frontend. Emphasizes E2E tests over unit tests, minimal mocking, and testing behavior over implementation details. Use when writing tests or reviewing test code.

...Expand all
53
Updated time July 7, 2026

About frontend-testing-best-practices

The frontend-testing-best-practices skill provides comprehensive guidelines for writing effective, maintainable tests for frontend applications. It addresses the common problem of writing tests that are brittle, hard to maintain, and provide false confidence by focusing on implementation details rather than user behavior. This skill emphasizes a philosophy that prioritizes end-to-end (E2E) tests over unit tests, minimal mocking, and testing behavior rather than implementation details.

The skill contains 6 core rules organized into three categories: Testing Strategy (critical level), E2E Tests (high priority), and Unit Tests (medium priority). Key capabilities include guidance on when to write E2E versus unit tests, how to structure E2E tests in the correct directory, best practices for using accessible selectors in Playwright tests, avoiding React component unit tests, and keeping mocks simple. The rules use practical code examples comparing good and bad approaches to make the guidelines immediately actionable.

This skill is ideal for frontend developers working on web applications who need to make testing decisions, write new tests, or review test code. It's particularly valuable for teams using Playwright for E2E testing and React for UI components. Use this skill when deciding what type of test to write, implementing new test coverage, refactoring existing tests, or conducting code reviews of test files. The guidelines help teams avoid common testing anti-patterns and build test suites that provide real confidence in application behavior.

FAQ

When should I write unit tests versus E2E tests?

Default to E2E tests for most scenarios. Only write unit tests for pure functions that have no dependencies and perform isolated logic like data formatting or calculations. If you're testing anything that involves React components, API calls, or user interactions, write an E2E test instead.

What testing framework does this skill assume?

The skill uses Playwright for E2E testing examples and references MSW (Mock Service Worker) for API mocking. The React component examples suggest a JavaScript/TypeScript frontend stack, but the core principles apply to any frontend framework.

How many mocks are too many in a test?

If you need 3 or more mocks in a single test, that's a signal to write an E2E test instead. Simple mocks (like a single MSW handler for an API endpoint) are fine, but complex mock setups indicate you should test the real integrated system.

Where should E2E tests be located in the project?

E2E tests should be placed in the e2e/tests/ directory at the project root, not within the frontend/ directory. This keeps them separate from unit tests and makes it clear they test the entire system.

What selector strategy should I use in Playwright tests?

Follow this priority: role-based selectors (getByRole) are preferred, then label-based (getByLabel), then text content, and finally test IDs (getByTestId) only when no accessible selector exists. Avoid CSS selectors as they are brittle and don't reflect how users interact with the application.

View on GitHub

Testing Best Practices

Guidelines for writing effective, maintainable tests that provide real confidence. Contains 6 rules focused on preferring E2E tests, minimizing mocking, and testing behavior over implementation.

Core Philosophy

  1. Prefer E2E tests over unit tests - Test the whole system, not isolated pieces
  2. Minimize mocking - If you need complex mocks, write an E2E test instead
  3. Test behavior, not implementation - Test what users see and do
  4. Avoid testing React components directly - Test them through E2E

When to Apply

Reference these guidelines when:

  • Deciding what type of test to write
  • Writing new E2E or unit tests
  • Reviewing test code
  • Refactoring tests

Rules Summary

Testing Strategy (CRITICAL)

prefer-e2e-tests - @rules/prefer-e2e-tests.md

Default to E2E tests. Only write unit tests for pure functions.

// E2E test (PREFERRED) - tests real user flowtest("user can place an order", async ({ page }) => {  await createTestingAccount(page, { account_status: "active" });  await page.goto("/catalog");  await page.getByRole("heading", { name: "Example Item" }).click();  await page.getByRole("link", { name: "Buy" }).click();  // ... complete flow  await expect(page.getByAltText("Thank you")).toBeVisible();});// Unit test - ONLY for pure functionstest("formatCurrency formats with two decimals", () => {  expect(formatCurrency(1234.5)).toBe("$1,234.50");});

avoid-component-tests - @rules/avoid-component-tests.md

Don't unit test React components. Test them through E2E or not at all.

// BAD: Component unit testdescribe("OrderCard", () => {  test("renders amount", () => {    render(<OrderCard amount={100} />);    expect(screen.getByText("$100")).toBeInTheDocument();  });});// GOOD: E2E test covers the component naturallytest("order history shows orders", async ({ page }) => {  await page.goto("/orders");  await expect(page.getByText("$100")).toBeVisible();});

minimize-mocking - @rules/minimize-mocking.md

Keep mocks simple. If you need 3+ mocks, write an E2E test instead.

// BAD: Too many mocks = write E2E testvi.mock("~/lib/auth");vi.mock("~/lib/transactions");vi.mock("~/hooks/useAccount");// GOOD: Simple MSW mock for loader testmockServer.use(  http.get("/api/user", () => HttpResponse.json({ name: "John" })),);

E2E Tests (HIGH)

e2e-test-structure - @rules/e2e-test-structure.md

E2E tests go in e2e/tests/, not frontend/.

// e2e/tests/order.spec.tsimport { test, expect } from "@playwright/test";import { addAccountBalance, createTestingAccount } from "./utils";test.describe("Orders", () => {  test.beforeEach(async ({ page, context }) => {    await createTestingAccount(page, { account_status: "active" });    let cookies = await context.cookies();    let account_id = cookies.find((c) => c.name === "account_id").value;    await addAccountBalance({ account_id, amount: 10000, replaceBalance: true });  });  test("place order with default values", async ({ page }) => {    await page.goto("/catalog");    // ... user flow  });});

e2e-selectors - @rules/e2e-selectors.md

Use accessible selectors: role > label > text > testid.

// GOOD: Role-based (preferred)await page.getByRole("button", { name: "Submit" }).click();await page.getByRole("heading", { name: "Dashboard" });// GOOD: Label-basedawait page.getByLabel("Email").fill("[email protected]");// OK: Test ID when no accessible selector existsawait expect(page.getByTestId("balance")).toHaveText("$1,234");// BAD: CSS selectorsawait page.locator(".btn-primary").click();

Unit Tests (MEDIUM)

unit-test-structure - @rules/unit-test-structure.md

Unit tests for pure functions only. Co-locate with source files.

// app/utils/format.test.tsimport { describe, test, expect } from "vitest";import { formatCurrency } from "./format";describe("formatCurrency", () => {  test("formats positive amounts", () => {    expect(formatCurrency(1234.5)).toBe("$1,234.50");  });  test("handles zero", () => {    expect(formatCurrency(0)).toBe("$0.00");  });});

Key Files

  • e2e/tests/ - E2E tests (Playwright)
  • e2e/tests/utils.ts - E2E test utilities
  • vitest.config.ts - Unit test configuration
  • vitest.setup.ts - Global test setup with MSW
  • app/utils/test-utils.ts - Unit test utilities

Install frontend-testing-best-practices

Download and extract the skill files to your .claude/skills/ directory.

Download ZIP

Clone the repository and copy the skill files to your project.

git clone https://github.com/sergiodxa/agent-skills/blob/main/skills/frontend-testing-best-practices/SKILL.md # Copy SKILL.md to your .claude/skills/ directory

Copy Copy
Quick Setup: Copy the skill folder to .claude/skills/Claude will automatically detect and use the skill

Related Skills

playwright-cli
Updated time June 29, 2026
Playwright Browser Automation
Updated time June 29, 2026
playwright-generate-test
Updated time June 29, 2026
playwright-expert
Updated time June 29, 2026
OR