All skills
sergiodxa avatar

/frontend-testing-best-practices

@4d1d816

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.

Use this Skill: https://skilld.dev/gh/sergiodxa/agent-skills/frontend-testing-best-practices

This session only. Nothing lands on disk.

SKILL.md

≈56 tokens always: the name and description. ≈1.1k when used: this file. ≈5.7k more on demand in 6 files.

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 flow
test("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 functions
test("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 test
describe("OrderCard", () => {
  test("renders amount", () => {
    render(<OrderCard amount={100} />);
    expect(screen.getByText("$100")).toBeInTheDocument();
  });
});

// GOOD: E2E test covers the component naturally
test("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 test
vi.mock("~/lib/auth");
vi.mock("~/lib/transactions");
vi.mock("~/hooks/useAccount");

// GOOD: Simple MSW mock for loader test
mockServer.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.ts
import { 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-based
await page.getByLabel("Email").fill("test@example.com");

// OK: Test ID when no accessible selector exists
await expect(page.getByTestId("balance")).toHaveText("$1,234");

// BAD: CSS selectors
await 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.ts
import { 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

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides a set of best practices and guidelines for frontend testing, focusing on E2E tests with Playwright and unit tests with Vitest. No security issues were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    7 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 4d1d816. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago
  • Testing
  • React
  • e2e-testing
  • playwright
  • vitest
  • behavior-testing
  • mocking
  • unit-tests
  • test-strategy

README badge

README badge for sergiodxa/agent-skills/frontend-testing-best-practices

Provides guidelines for frontend testing that prioritize end-to-end tests over unit tests, minimize mocking, and test user behavior rather than implementation details. Use when writing or reviewing test code for web applications built with Playwright and Vitest.

Generated from the current SKILL.md.

When should I write unit tests vs E2E tests?
Default to E2E tests for user workflows and features. Only write unit tests for pure functions. If you need 3 or more mocks for a unit test, write an E2E test instead.
Should I test React components directly?
No. Test components through E2E tests that exercise them in a real user flow, rather than isolated component unit tests.
What selectors should I use in E2E tests?
Prefer accessible selectors in this order: role-based (getByRole), label-based (getByLabel), text-based, then test IDs. Avoid CSS selectors.
What testing tools does this skill assume?
E2E tests use Playwright, unit tests use Vitest. MSW (Mock Service Worker) is used for simple API mocking.

Generated from the current SKILL.md. These answers refresh after source changes.