F34|工程质量的基础:需求、反例、测试与审查
从具体对象与小例子开始,理解计算过程与适用条件。
本章目录
测试是找反例,不是给代码盖绿章
为什么“测试都通过”仍可能交付错东西?
测试只能验证它实际检查的行为和版本。一条只断言“不报错”的测试无法证明排除规则正确。好的测试围绕需求构造能击中错误的输入;代码修改以后,旧绿色结果也不再自动属于新版本。
输入与适用条件:构造的文件筛选任务;通配符语义须由需求明确,不在动画里偷偷改变“匹配文件名”与“匹配完整路径”的规则。
1 / 6 · 明确需求
窄屏可左右滑动图形,或点击“放大图形”。文字解释紧随图后。
不先说匹配对象与目录语义,无法判断哪个输出才正确。
本步状态由图形与说明共同给出。默认静止。用“下一步”看完解释再继续;播放到最后一步自动停止。键盘聚焦播放器后,可用左右键逐步查看、空格播放/暂停。图中颜色辅助区分,含义同时用文字注明。
为什么需要
减少返工和虚假完成,而非让审查循环无限增长。
怎样实现
围绕可观察行为、反例和当前版本组织验证。
可能的代价与误解
测试与实现共用同一错误假设、只测顺利路径、频繁审查无实际修复。
如何判断是否做对
故意引入一处已知错误,测试应失败;恢复后再通过。
正确性首先相对于什么
“修复exclude”还不够明确。它应排除整个目录还是只排除一个路径?vendor2是否应被vendor匹配?是否支持绝对路径、反斜杠和空规则?
验收条件acceptance criteria把目标写成可检查行为;不变量描述改动不能破坏的约束。它们不要求大篇幅文档,几个明确的例子和禁止项通常比模糊长Prompt更有效。
一条测试包含什么
测试先准备输入和环境,再执行目标代码,最后比较实际结果与预期结果。断言assertion表达这种比较,例如期望is_excluded('vendor/a.py')为真。
如果预期值本身就是照模型输出抄的,测试可能只是“证明模型和自己一致”。测试判据oracle是用来判断正确结果的依据,应来自需求、可靠参考或独立推导。
单元、集成和端到端测试各看哪层
单元测试聚焦局部逻辑;集成测试看组件之间配合;端到端测试模拟较完整的用户流程。它们覆盖不同错误,不能无限用最慢的端到端测试代替所有局部验证。
例如路径函数单测通过,但上游调用前错误处理了分隔符,集成流程仍可能失败。相反,只跑一个大流程也可能难以定位哪段逻辑出错。
用反例识别弱测试
假设Agent把排除函数改成永远返回true,正向测试“vendor/a.py应被排除”会通过。加入反例“src/a.py不应被排除”,就能抓住这种假修复。
性质测试property-based testing不只检查固定例子,还检查许多生成输入是否满足一般性质。比如路径规范化后结果应保持等价;但性质也必须是真的,不能凭想象写一个错误规律。
变异测试mutation testing主动引入小错误,检查测试能否发现。测试不报错只证明在这些输入上未发现问题;能抓住针对性变异才更能说明测试有辨别力。
测试通过也必须绑定版本
在代码v1跑过测试后,又修改成v2,却继续引用v1结果,是过期验证。Agent最终交付需要把当前代码、测试范围、结果和未验证限制对应起来。
编译成功、测试通过和生产正确是不同层的证据。测试环境缺了外部依赖时,应明确未覆盖,而不是默认为成功。
Review怎样服务修改,而不是阻止一切变化
Review检查设计、功能、复杂度、测试和可维护性。它的目标是发现值得修正的问题,改善整体代码健康,不是无限追求不存在的零风险完美。
低风险小修改可直接实现并验证;复杂并发或跨模块改动更值得独立分析。审查发现的小问题可以在当前步骤修复并重测,不必每次回到起点重新生成整套方案。
为什么Prompt/Skill测试不能只看hash
对全文做哈希快照可以发现任意字节变化,却不区分改错别字和破坏规则含义。若每次改文案都更新预期hash,这类测试可能只制造维护工作。
更有价值的是行为回归:该加载的技能是否加载、不该加载的是否避免、关键约束能否影响真实动作、代码与验证是否满足目标。结构检查可以保留,但要明确它只能证明结构。
让一个反例证明补丁不是只迎合已有测试
输入与条件。需求:“排除目录a及其后代,但不能排除ab”。错误实现只检查字符串是否以a开头。
| 步骤与对象 | 内部动作 | 中间结果 / 新状态 |
|---|---|---|
| 1已有输入 | a/file.py | 被排除,符合需求。 |
| 2增加反例 | ab/file.py | 错误实现也排除,暴露路径边界问题。 |
| 3补充边界 | a本身、a/nested/x.py、空排除列表 | 分别覆盖目录本身、后代和默认行为。 |
| 4改实现 | 按路径分段比较祖先关系 | 让a和ab在段级别不同。 |
| 5重新验证 | 功能断言与相关回归同时运行 | 测试通过必须绑定修改后的版本。 |
把过程连起来。“有测试”不够,测试需要能区分正确语义与一个看起来合理的错误实现。
边界与反例。本例仅为路径段语义;真实跨平台路径还涉及分隔符、规范化、符号链接和安全边界。
依据与适用范围:[DERIVE]。示例输入和场景由本书明确设定。
课后自检
函数永远返回true能通过一个正向测试,说明什么?
查看参考答案收起参考答案
代码又改了,但测试未重跑,能沿用之前全绿结论吗?
查看参考答案收起参考答案
延伸阅读:相关系统问题
17|代码智能:从文本搜索到符号、版本与运行证据20|多Agent:并行的收益与交接的损失
22|工程质量:从需求到测试,再到真正可交付的代码
23|Evaluation:怎样证明一次优化真有收益
26|深度应用:把组件组合成能解释的工作系统
机制依据:[REVIEW][SWEBENCH][EVALS]。本节数值与情景除另注外均为原创教学示例;来源不代替中文讲解。