Harness不是测试工具,而是开发控制面
如果把 Harness 只理解成测试工具,就会错过它最有价值的部分。
测试工具回答的是:这段代码在给定条件下会不会按预期运行。开发 Harness 回答的是:这个任务从被提出到被交付,中间每一步有没有失真、有没有越界、有没有证据、有没有停损点。
测试工具通常包住代码。开发 Harness 包住过程。
一、Test Harness 给我们的启发
一个好的 test harness 会做几件事:
- 准备被测对象。
- 构造输入。
- 替换外部依赖。
- 控制时间、网络、数据库、文件系统等不稳定因素。
- 执行动作。
- 观察输出。
- 断言结果。
- 清理环境。
它真正重要的地方,不是“测试”这个词,而是“可控环境”。
没有 Harness 时,代码跑在真实世界里,依赖太多,状态太乱,失败难以复现。有了 Harness,代码被放进一个小型控制舱:输入可知、依赖可知、输出可测。
这件事可以迁移到整个开发过程。
一个需求也是被测对象。它进入开发系统时,天然带着模糊、噪声和缺口。如果不把它放进 Harness,它会在每个阶段变形。最后你得到的不是“解决了问题的代码”,而是“根据一串未验证假设生成的代码”。
二、开发 Harness 控制五件事
开发 Harness 至少有五个控制点。
第一,方向。
方向由 Mode、问题定义、In Scope、Out of Scope 控制。它解决的是“我们到底在做什么”。如果方向没控住,后面所有努力都可能是在加速偏离。
第二,事实。
事实由 Research 控制。它解决的是“我们凭什么这么判断”。开发中最危险的不是未知,而是把未知伪装成已知。Research 要把 Facts、Assumptions、Unknowns 分开。
第三,设计边界。
设计边界由需求、技术设计和实施计划控制。它解决的是“允许怎样改,不允许怎样改”。这里要明确状态流、接口契约、错误态、回滚、监控、验证方式和停损点。
第四,执行。
执行由任务切片、文件边界、测试先行、diff review 控制。它解决的是“怎么保证改动没有偷偷扩大”。AI 参与时尤其重要,因为 AI 很容易把“顺手”变成“已经改了”。
第五,证据。
证据由测试计划、review finding、验收记录、发布报告和复盘控制。它解决的是“我们怎么知道这次真的完成了”。没有证据,完成只是情绪。
三、为什么只靠测试不够
测试很重要,但测试不能替代开发 Harness。
测试通常发生在实现之后。它可以告诉你代码行为是否符合某个预期,但它不一定告诉你预期是否正确。如果问题定义错了,测试越全,越稳定地证明一个错误目标被实现了。
测试通常覆盖代码路径,但不一定覆盖任务边界。一个功能测试通过了,不代表这次没有顺手改坏别的契约。
测试通常验证可观察行为,但不一定验证运维后果。代码能跑,不代表日志足够、指标足够、回滚可行、失败能被发现。
测试通常对付明确输入,但开发失控常常来自隐含输入:一句模糊需求、一个不完整上下文、一段 AI 自行补全的假设。
所以测试是 Harness 的一部分,但不是全部。
更准确地说:
测试 Harness 控制代码运行环境;开发 Harness 控制代码产生过程。
四、一个简单例子
假设任务是:“把文章导出功能优化一下,最近偶尔失败。”
没有开发 Harness 的过程可能是:
- 搜索 export。
- 看到异常日志。
- 猜测是超时。
- 增加重试。
- 补一个成功导出的测试。
- 写结论:已优化。
这个过程很快,但风险很多。
“偶尔失败”到底是什么失败?是生成失败、上传失败、权限失败、任务队列失败、文件过大失败,还是前端轮询超时?
“优化”是什么意思?降低失败率、缩短耗时、改善错误提示、增加重试、增强幂等、补偿历史失败任务,还是增加可观测性?
“增加重试”会不会导致重复导出?会不会重复扣额度?会不会把不可重试错误重试三次?会不会隐藏真正的权限问题?
如果这些都没问,测试成功也只能证明一个很窄的成功路径。
同一个任务放进开发 Harness,过程会变成:
- Mode:Hold,只修复和硬化导出失败,不扩展新导出格式。
- Research:列出现有导出链路、失败日志、触发条件、相关文件、已有测试。
- Problem Framing:确认问题是“导出任务在上传成功但状态写回失败时,会被用户看到为失败且无法恢复”。
- Technical Design:设计幂等 key、状态机、错误分类、日志指标、回滚方式。
- Implementation Plan:分阶段改状态机、补测试、补指标。
- Execution:只改批准文件。
- Review:按 happy、nil、empty、error 检查。
- Test Plan:记录每条验证命令和证据。
- Acceptance:明确剩余风险和是否可发布。
这不是慢。这是把“快但可能错”改成“每一步都知道为什么”。
五、Harness 的几个误区
第一个误区:Harness 等于更多文档。
坏文档确实会拖慢开发。但 Harness 的目标不是写更多字,而是让关键信息不丢。一个好的问题定义可能只有半页,但它能阻止三天偏航。一个好的测试证据台账可能只有一张表,但它能让上线后的复盘有抓手。
第二个误区:Harness 只适合大项目。
小任务更需要轻量 Harness。因为小任务最容易让人觉得“这点事直接改就行”。很多事故不是大项目造成的,而是小改动没有边界、没有测试、没有 review。
第三个误区:AI 可以替代 Harness。
AI 可以帮你生成 Harness 文档,但不能替你决定边界。AI 可以帮你补测试,但不能替你判断哪些风险值得覆盖。AI 可以帮你 review,但如果你没要求它按四路径 review,它很可能给你一段温顺的总结。
第四个误区:Harness 会压制创造力。
真正压制创造力的是混乱。因为混乱会让所有精力都耗在补洞、解释、返工和救火上。Harness 把基本控制面固定住,反而释放了更多思考空间。
六、最小形态
如果一个任务很小,不需要完整文档链,也至少保留最小 Harness:
1 | Mode: |
这些字段看起来普通,但它们分别控制不同失控点:
- Mode 控制变化方向。
- In Scope 控制本次要做什么。
- Out of Scope 控制本次不做什么。
- Facts 控制证据。
- Assumptions 防止猜测伪装成事实。
- Plan 控制执行顺序。
- Validation 控制完成证据。
- Review Paths 控制边界路径。
- Residual Risk 控制诚实收尾。
任务变大时,把它展开成完整流程。任务变小时,把它压缩成这几个字段。
Harness 不是仪式,它是可伸缩的控制面。