frontend-testing-best-practices
sergiodxa/agent-skills
E2E-first testing guidelines emphasizing behavior over implementation and minimal mocking.
What is frontend-testing-best-practices?
Testing best practices for frontend development that prioritize end-to-end tests over unit tests, minimize mocking, and focus on testing user behavior rather than implementation details. Use when writing new tests, reviewing test code, or deciding what type of test to write.
- Prefer E2E tests over unit tests for comprehensive system coverage
- Minimize mocking—if you need 3+ mocks, write an E2E test instead
- Test user behavior and what users see, not React component internals
- Use accessible selectors (role > label > text > testid) in E2E tests
- Structure E2E tests in e2e/tests/ with proper setup utilities
- Write unit tests only for pure functions, co-located with source files
How to install frontend-testing-best-practices
npx skills add https://github.com/sergiodxa/agent-skills --skill frontend-testing-best-practicesHow to use frontend-testing-best-practices
- 1.Reference the core philosophy when deciding test type: prefer E2E tests and minimize mocking
- 2.Use role-based selectors in E2E tests (getByRole) before falling back to testid
- 3.Place E2E tests in e2e/tests/ directory with Playwright configuration
- 4.Write unit tests only for pure functions and co-locate them with source files
- 5.Use test utilities from e2e/tests/utils.ts for common setup (accounts, balances, etc.)
- 6.Review existing tests against the 6 rules to identify over-mocked or implementation-focused tests
Use cases
- Deciding whether to write an E2E test or unit test for a feature
- Reviewing test code to ensure it follows behavior-driven principles
- Refactoring existing unit tests that over-mock dependencies
- Setting up E2E test structure with Playwright and test utilities
- Writing tests for user flows like placing orders or account management
- Frontend developers writing or reviewing tests
- QA engineers designing test strategies
- Teams adopting behavior-driven testing practices
- Projects using Playwright for E2E testing
frontend-testing-best-practices FAQ
Write E2E tests by default to test real user flows. Only write unit tests for pure functions (like formatCurrency). If you need 3+ mocks for a unit test, write an E2E test instead.
No. Avoid unit testing React components. Test them through E2E tests where they're used in real user flows, or don't test them at all.
Use accessible selectors in order of preference: role-based (getByRole), label-based (getByLabel), text content, then testid. Avoid CSS selectors.
E2E tests go in e2e/tests/ directory, not in the frontend/ directory. Use Playwright and co-locate test utilities in e2e/tests/utils.ts.
Keep mocks simple and minimal. If you find yourself creating 3 or more mocks for a test, that's a signal to write an E2E test instead.
Full instructions (SKILL.md)
Source of truth, from sergiodxa/agent-skills.
name: frontend-testing-best-practices description: 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.
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
- Prefer E2E tests over unit tests - Test the whole system, not isolated pieces
- Minimize mocking - If you need complex mocks, write an E2E test instead
- Test behavior, not implementation - Test what users see and do
- 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 utilitiesvitest.config.ts- Unit test configurationvitest.setup.ts- Global test setup with MSWapp/utils/test-utils.ts- Unit test utilities
Related skills
More from sergiodxa/agent-skills and the wider catalog.

owasp-security-check
Security audit guidelines for web applications and REST APIs based on OWASP Top 10 and web security best practices. Use when checking code for vulnerabilities, reviewing auth/authz, auditing APIs, or before production deployment.

frontend-react-best-practices
React performance optimization guidelines. Use when writing, reviewing, or refactoring React components to ensure optimal rendering and bundle patterns. Triggers on tasks involving React components, hooks, memoization, or bundle optimization.

123movies-downloader
Download movies and TV shows from 123movies instantly without ads or popups

123rf-downloader
Save 123RF stock photos and vectors without watermarks in original quality

adobe-stock-downloader
Download Adobe Stock images

alamy-downloader
Extract Alamy stock photos in full resolution without watermarks or restrictions