mcpField
T
testing-best-practices

testing-best-practices

github.com/andrelandgraf测试与质量23102 次安装21 周前更新
代码仓库

关于 testing-best-practices

这项测试技能帮助开发者在 Playwright、集成测试和单元测试之间做选择,并规划测试数据。它说明如何在隔离且会自动删除的 Neon 分支上运行测试。

主要功能

  1. 01测试类型选择指南
  2. 02Playwright、集成和单元测试模式
  3. 03使用临时 Neon 分支运行测试
  4. 04按测试套件隔离数据
  5. 05调试命令与测试产物说明

适用场景

  1. 01为功能选择合适的测试层级
  2. 02在隔离的数据库状态上运行测试套件
  3. 03排查 Playwright 或单元测试失败

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/testing-best-practices确认已加载。

详细介绍

测试最佳实践

选择合适的测试类型,为每个测试套件隔离数据,并在临时 Neon 分支上运行测试。

前置条件

请先完成以下设置指南:

  • 使用 Playwright 进行浏览器测试
  • 集成测试
  • 使用 Bun 进行单元测试
选择测试类型

问问自己“用户会如何验证此功能正常运行?”,然后选择适用范围内最高的测试层级:

  1. Playwright(默认)——UI 交互、视觉反馈、表单验证、多步骤流程、受保护的路由、无障碍功能。
  2. 集成测试——API 响应(状态码、JSON 结构)、操作后的数据库状态、不涉及 UI 的服务端逻辑,或 Playwright 测试过慢/过于复杂时。
  3. 单元测试——包含复杂逻辑或许多边界情况的纯函数,或没有外部依赖的类型收窄/断言。
运行测试

所有测试都在一个隔离的、仅包含 schema 的 Neon 分支上运行,该分支会在 1 小时后自动删除。

bun run test              # all tests
bun run test:playwright   # browser only
bun run test:integration  # integration only
bun run test:unit         # unit only
文件夹结构

单元测试与被测代码放在一起;Playwright 测试和集成测试位于 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
编写测试

Playwright 测试文件:

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

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

集成测试——直接导入路由处理程序,而不是通过 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();
  });
});

单元测试(与被测代码放在一起):

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

describe("myFunction", () => {
  it("returns expected value", () => {
    expect(myFunction()).toBe("expected");
  });
});
测试数据隔离

测试会并行使用共享分支,因此每个测试套件都必须拥有自己的数据。为每个测试文件生成唯一用户(例如 auth-test-${uuid}@example.com),避免共享资源,并依靠分支的 TTL 进行清理——绝不要假设其他测试中的数据存在。

const testUser = await createTestUser({
  email: `auth-test-${uuid}@example.com`,
});
常见模式
// 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,
  });
});
调试
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

Playwright 运行失败时,会将屏幕截图和跟踪记录保存到 test-results/——CI 失败时请检查此目录。

评论

支持 Markdown