OpenClaw 中观察到的测试模式
本文档基于代码库分析,记录了关于 OpenClaw 测试框架、文件组织和测试执行模式的观察。这些模式确保测试与 CI 无缝集成。
测试框架: Vitest
OpenClaw 使用 Vitest 作为其测试框架,并使用 V8 覆盖率提供程序。
为什么选择 Vitest
- 具有原生 ESM 支持的快速测试执行
- 与 Vite 生态系统兼容
- 使用 V8 的内置覆盖率(没有 Istanbul 开销)
- 原生 TypeScript 支持
Vitest 配置
配置位于存储库根目录的 vitest.config.ts 中。
关键配置设置
池配置: Forks,而不是 Threads
pool: "forks"- 每个测试文件在单独的进程中运行- 最大 worker 数: CI 使用 2-3 个 worker,本地开发上限为 16 个 worker
- 为什么使用 forks? - 更好的隔离,避免原生模块的共享内存问题
超时
- 测试超时: 120 秒(2 分钟)
- 钩子超时: 本地 120 秒,CI 180 秒
- 长超时适应集成测试和网关操作
环境 Stubbing
unstubEnvs: true- 测试看到真实的环境变量unstubGlobals: true- 测试看到真实的全局对象- 确保测试在真实条件下运行
覆盖率配置
覆盖率阈值
覆盖率要求
- 70% 行数、函数和语句 - 必须覆盖大部分代码路径
- 55% 分支 - 条件逻辑的较低阈值
- V8 提供程序 - 原生覆盖率,无插桩开销
测试文件模式
同位置测试(标准模式)
测试文件位于源文件旁边,而不是在单独的 test/ 目录中。
模式: src/**/*.test.ts
示例结构:
为什么同位置? - 更容易找到相关测试,更好的封装
E2E 测试
模式: *.e2e.test.ts
E2E 测试验证端到端工作流(例如,完整的网关请求周期)。
示例: src/gateway/gateway.e2e.test.ts
Live 测试
模式: *.live.test.ts
Live 测试需要外部服务(例如,真实的 Anthropic API)。
运行: LIVE=1 pnpm test 或 pnpm test:live
示例: src/agents/anthropic.live.test.ts
测试结构
标准导入
所有测试实用程序来自 Vitest - 无需单独的断言库
Hoisted 模拟
使用 vi.hoisted() 来定义需要在导入之前定义的模拟。
观察到的模式:
模块模拟
使用 vi.mock() 来替换整个模块。
观察到的模式:
测试工具和辅助函数
复杂的设置使用专用的工具文件。
观察到的模式:
*.test-harness.ts- 复杂的测试装置和设置*.test-helpers.ts- 可重用的测试实用程序
示例: src/gateway/gateway.test-harness.ts 提供模拟网关上下文
设置文件
全局测试设置在 test/setup.ts 中。
关键设置函数: withIsolatedTestHome()
目的: 为每个测试创建隔离的主目录
观察到的模式:
为什么? - 通过共享配置文件防止测试干扰
运行测试
标准命令
低内存测试
对于 CI 或资源受限的环境:
这样做的作用:
OPENCLAW_TEST_PROFILE=low- 减少并行 workerOPENCLAW_TEST_SERIAL_GATEWAY=1- 串行运行网关测试(而非并行)
常见测试模式
用于组织的 Describe 块
使用 await 的异步测试
使用 afterEach 清理
为什么? - 防止模拟状态在测试之间泄漏
测试隔离最佳实践
始终重置模拟
在 afterEach 块中使用 vi.clearAllMocks() 或 vi.resetAllMocks()。
使用隔离的测试主目录
对于触及配置文件的测试,始终在 beforeEach 中调用 withIsolatedTestHome()。
避免共享状态
不要依赖测试执行顺序。每个测试应该是独立的。
CI 注意事项
并行执行
测试默认并行运行。如果需要,使用 OPENCLAW_TEST_SERIAL_GATEWAY=1。
覆盖率执行
如果不满足覆盖率阈值(70% 行数,55% 分支),CI 将失败。
超时失败
如果测试在 CI 中超时但在本地通过,请检查:
- 钩子超时设置(CI 中为 180 秒,本地为 120 秒)
- 集成测试的网络延迟
- 资源争用(使用低内存配置文件)
为什么这很重要
遵循这些模式可确保:
- CI 通过 - 测试在 CI 环境中可靠运行
- 隔离 - 测试不会相互干扰
- 覆盖率 - 代码满足质量阈值
- 可维护性 - 同位置测试易于查找和更新
- 性能 - Fork 池和 V8 覆盖率提供快速执行