mcpField
T
testing-best-practices

testing-best-practices

github.com/andrelandgrafTesting & quality23102 installsUpdated 21w ago
Repository

About testing-best-practices

A testing skill that helps developers choose between Playwright, integration, and unit tests and organize test data. It describes running suites against an isolated, disposable Neon branch.

Key features

  1. 01Guidance for choosing test types
  2. 02Playwright, integration, and unit patterns
  3. 03Disposable Neon branch for test runs
  4. 04Per-suite test data isolation
  5. 05Commands and artifacts for debugging

Use cases

  1. 01Select a test tier for a feature
  2. 02Run suites against isolated database state
  3. 03Debug failed Playwright or unit tests

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/andrelandgraf/fullstackrecipes --skill testing-best-practices

After installing, type/testing-best-practicesin Claude Code to confirm it loaded.

Details

From the project README

Testing Best Practices

Choose the right test type, isolate data per suite, and run against a disposable Neon branch.

Prerequisites

Complete these setup recipes first:

  • Browser Tests with Playwright
  • Integration Tests
  • Unit Tests with Bun
Choosing a Test Type

Ask "how would a user verify this works?" and pick the highest applicable tier:

  1. Playwright (default) — UI interactions, visual feedback, form validation, multi-step flows, protected routes, accessibility.
  2. Integration — API responses (status, JSON shape), DB state after operations, server logic without UI, or when Playwright is too slow/complex.
  3. Unit — pure functions with complex logic, many edge cases, or type narrowing/assertions with no external dependencies.
Running

All tests run against an isolated, schema-only Neon branch that auto-deletes after 1 hour.

bun run test              # all tests
bun run test:playwright   # browser only
bun run test:integration  # integration only
bun run test:unit         # unit only
Folder Structure

Unit tests are co-located; Playwright and integration tests live under tests/.

src/lib/<domain>/<file>.test.ts   # unit (co-located)
tests/integration/<feature>.test.ts
tests/playwright/<feature>.spec.ts
tests/playwright/lib/                # Playwright helpers
Writing Tests

Playwright spec:

import { test, expect } from "@playwright/test";

test.describe("Feature Name", () => {
  test("should do expected behavior", async ({ page }) => {
    await page.goto("/feature");
  });
});

Integration — import the route handler directly instead of going over HTTP:

import { describe, it, expect } from "bun:test";
import { GET } from "@/app/api/feature/route";

describe("GET /api/feature", () => {
  it("returns expected response", async () => {
    const response = await GET();
    expect(response.status).toBe(200);
    const data = await response.json();
    expect(data.value).toBeDefined();
  });
});

Unit (co-located):

import { describe, it, expect } from "bun:test";
import { myFunction } from "./my-file";

describe("myFunction", () => {
  it("returns expected value", () => {
    expect(myFunction()).toBe("expected");
  });
});
Test Data Isolation

Tests run in parallel against the shared branch, so each suite must own its data. Generate unique users per spec (e.g. auth-test-${uuid}@example.com), avoid shared resources, and rely on the branch TTL for cleanup — never assume data from another test exists.

const testUser = await createTestUser({
  email: `auth-test-${uuid}@example.com`,
});
Common Patterns
// Protected route (Playwright)
test("redirects unauthenticated user", async ({ page }) => {
  await page.goto("/protected-page");
  await expect(page).toHaveURL(/sign-in/);
});

// Error state (Playwright)
test("shows error for invalid input", async ({ page }) => {
  await page.goto("/form");
  await page.getByRole("button", { name: /submit/i }).click();
  await expect(page.getByText(/error|required/i)).toBeVisible({
    timeout: 5000,
  });
});
Debugging
bunx playwright test --headed     # watch the browser
bunx playwright test --debug      # step through
bunx playwright show-report       # HTML report

bun test --only "test name"       # run a single test
bun test --watch                  # re-run on change

Failed Playwright runs save screenshots and traces to test-results/ — check there when CI fails.

Comments

Markdown supported