跳转到内容

测试策略:Vitest + Playwright + Cucumber 三层测试

学习目标

理解 LobeHub 的三层测试体系(Vitest 单元测试、Playwright E2E、Cucumber 行为驱动),以及测试偏好和陷阱规避。

前置知识

本章无通用知识前置,直接聚焦 LobeHub 的工程实践。

项目实践

三层测试架构

单元测试:Vitest

Terminal window
# 运行特定文件测试(推荐方式)
bunx vitest run --silent='passed-only' 'path/to/file.test.ts'
# 数据库包独立测试
cd packages/database && bunx vitest run --silent='passed-only' 'file.test.ts'
# ❌ 禁止:全局运行(耗时约 10 分钟)
# bun run test

关键约束:AGENTS.md 中明确禁止 bun run test,因为运行全部测试耗时过长。只应运行特定文件的测试。

测试偏好:vi.spyOn 优于 vi.mock

// ✅ 推荐:使用 vi.spyOn
const spy = vi.spyOn(repository, "findById");
spy.mockResolvedValue(mockAgent);
// ❌ 不推荐:使用 vi.mock
vi.mock("@/repositories", () => ({
AgentRepository: vi.fn(() => ({ findById: vi.fn() })),
}));

原因

  • vi.spyOn 只修改特定方法,保留模块的其他行为
  • vi.mock 替换整个模块,可能导致意想不到的副作用
  • vi.spyOn 更易于理解和调试

类型安全检查

测试必须通过类型检查:

Terminal window
bun run type-check # tsc --noEmit 或 tsgo --noEmit

如果测试代码有类型错误,CI 会失败。这确保测试不仅运行时正确,编译期也正确。

E2E 测试:Playwright + Cucumber

E2E 测试使用 Cucumber 的行为驱动开发(BDD)模式:

# 伪代码:Feature 文件
Feature: Agent 创建
Scenario: 用户创建新 Agent
Given 用户已登录
When 用户点击 "新建 Agent"
And 输入 Agent 名称 "测试 Agent"
And 点击 "创建"
Then Agent 列表中出现 "测试 Agent"

Step 定义使用 Playwright 浏览器自动化:

// 伪代码:Step 定义
Given("用户已登录", async function () {
await this.page.goto("/login");
await this.page.fill('[data-testid="email"]', TEST_USER_EMAIL);
await this.page.click('[data-testid="login"]');
});

DesktopRouter 同步测试

src/spa/router/desktopRouter.sync.test.tsx
// 验证两个 desktopRouter config 文件的路线树完全同步

这是一个专门的同步测试,确保 desktopRouter.config.tsxdesktopRouter.config.desktop.tsx 中注册的路线一致。如果不同步,测试失败。

问题与规避

问题场景规避策略
全局测试超时bun run test 运行 10+ 分钟只运行特定文件的测试
类型检查失败测试代码使用 any 绕过类型CI 中 type-check 步骤检测
Mock 副作用vi.mock 替换整个模块导致意外使用 vi.spyOn 只修改特定方法
E2E 不稳定Playwright 浏览器环境差异在 CI 中使用固定版本的 Playwright 和浏览器
数据库测试污染多个测试共享数据库每个测试使用独立事务或清理

设计取舍

为什么 Cucumber 而非纯 Playwright 测试?

Cucumber 的 Gherkin 语法(Given/When/Then)使得测试用例可以作为需求文档阅读。产品经理和非开发人员也可以理解和编写测试用例。

代价:Cucumber 增加了一层抽象,step 定义的实现可能与 Gherkin 描述不同步。

为什么禁止全局测试运行?

70+ 包的 monorepo 中,全局测试耗时过长(约 10 分钟),阻塞开发流程。针对性的文件级测试在几秒内完成反馈。

替代方案:Turborepo 缓存测试,只运行受影响包的测试。LobeHub 目前通过文件路径指定测试来实现等效效果。

参考来源

  • LobeHub Vitest 配置 — vitest.config.mts
  • LobeHub E2E 测试 — e2e/ 目录
  • LobeHub AGENTS.md — 开发指南中的测试约束