09 · 测试与证据
验证外部世界,选最小证据
关键文件
docs/testing.md.agents/skills/dsh-pre-push-checks/.agents/skills/dsh-ci-test-reliability/snapshots/AGENTS.md.github/pull_request_template.md测试分层
| 层 | 命令 | 作用 |
|---|---|---|
| 单元 | pnpm run test | 包内 tests/ 和脚本 spec;每个注册表都有 HMR 安全测试 |
| 覆盖率门禁 | pnpm run test:coverage | CI 上的真正门禁,每文件 100% |
| 真实 API e2e | pnpm run test:e2e | 对真实模型运行,没有 key 时自动跳过 |
| 录制会话 snapshot | pnpm run test:snapshot | 无 key 回放,比对持久化结果 |
| Web 浏览器 | pnpm run test:web | Chromium 里比对 UI 与 ARIA 输出 |
| 性能 | pnpm run test:bench | 时间、堆内存和规模预算 |
| 本地预期输出 | pnpm run test:expected | 不经录制会话的 CLI/进程预期 |
让绿色的测试有意义
- 验证外部世界,不信自述。e2e 断言要重新执行命令或从外部读文件。只检查 agent 输出里有没有关键词,作弊的 agent 也能通过。没被改动的文件要断言字节相同。
- 测试真实入口。产品可见的插件需要一个经过 Loader 和真实进程的组合测试,手工
ctx.plugin(...)不够。包的bin要在纯 node 下运行构建产物,以暴露 tsx 掩盖的问题。 - 只 mock 昂贵或不确定的部分:LLM 适配器、网络、时钟。下游全部用真实实现。
- 守卫要能失败。引入回归,看着测试变红,再还原。
dsh-code-review把它列为"负向对照"检查。 - 覆盖率是必要条件,不是证据。它只证明代码执行过,不证明功能按交付状态工作。
- 只在单独运行时通过的 spec 是 spec 的缺陷。spec 和其他门禁进程并发运行,要自己管理端口、临时路径和子进程。
推送前:按改动面选证据
dsh-pre-push-checks 反对"不知道该跑什么就全跑一遍"。先用 pnpm --silent run change-scope --base <已核实的 base> 看清改动范围,再按改动类型挑选能捕获其回归的最窄检查:
| 改动 | 证据 |
|---|---|
| 包或脚本行为 | 所属的 Vitest 文件或聚焦的测试名 |
| 文档、Agent Note、目录、文档链接的注释 | pnpm run doc-sync |
| 模型、编辑器、CLI 或终端可见的输出 | 对应的 snapshot 场景 |
| 包清单、公共导出、构建配置、bin | pnpm run build 加相关 hygiene 检查和构建产物冒烟测试 |
| TypeScript 改动,声称完成之前 | 最近一次 build:artifacts 之后跑 build:check |
| 真实提供商或 agent 行为 | pnpm run test:e2e(有 key 时) |
不要因为马上要 commit 或 push 就重复已经通过的检查;汇报时只列实际运行过的命令。PR 模板的 Testing 区为每种测试方法提供一个折叠的 Proof 区,用来放测试输出、截图或日志。