基础篇

F34|工程质量的基础:需求、反例、测试与审查

基础篇约 2.4 千字1 组分步图解

从具体对象与小例子开始,理解计算过程与适用条件。

本章目录
动态图解 · F34

测试是找反例,不是给代码盖绿章

为什么“测试都通过”仍可能交付错东西?

测试只能验证它实际检查的行为和版本。一条只断言“不报错”的测试无法证明排除规则正确。好的测试围绕需求构造能击中错误的输入;代码修改以后,旧绿色结果也不再自动属于新版本。

反例能让错误实现暴露问题的具体输入。
回归修改破坏了本来成立的行为。
交付证据当前版本对应的检查命令、结果与范围。

输入与适用条件:构造的文件筛选任务;通配符语义须由需求明确,不在动画里偷偷改变“匹配文件名”与“匹配完整路径”的规则。

1 / 6 · 明确需求

第1步,共6步

窄屏可左右滑动图形,或点击“放大图形”。文字解释紧随图后。

测试是找反例,不是给代码盖绿章:明确需求明确需求排除*.tmp,但保留其余文件构造小反例a.py、b.tmp、nested/c.tmp先看原始失败确认旧代码确实没有正确排除实施最小修改修复匹配语义,不改无关API测试针对行为检查保留、排除、嵌套和空规则绑定版本交付绿色结果属于当前代码,而非旧文件教学流程;高亮表示当前步骤,不表示真实耗时比例。

不先说匹配对象与目录语义,无法判断哪个输出才正确。

本步状态由图形与说明共同给出。

默认静止。用“下一步”看完解释再继续;播放到最后一步自动停止。键盘聚焦播放器后,可用左右键逐步查看、空格播放/暂停。图中颜色辅助区分,含义同时用文字注明。

为什么需要

减少返工和虚假完成,而非让审查循环无限增长。

怎样实现

围绕可观察行为、反例和当前版本组织验证。

可能的代价与误解

测试与实现共用同一错误假设、只测顺利路径、频繁审查无实际修复。

如何判断是否做对

故意引入一处已知错误,测试应失败;恢复后再通过。

正确性首先相对于什么

“修复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,这类测试可能只制造维护工作。

更有价值的是行为回归:该加载的技能是否加载、不该加载的是否避免、关键约束能否影响真实动作、代码与验证是否满足目标。结构检查可以保留,但要明确它只能证明结构。

运行示例 · F34

让一个反例证明补丁不是只迎合已有测试

输入与条件。需求:“排除目录a及其后代,但不能排除ab”。错误实现只检查字符串是否以a开头。

步骤与对象内部动作中间结果 / 新状态
1已有输入a/file.py被排除,符合需求。
2增加反例ab/file.py错误实现也排除,暴露路径边界问题。
3补充边界a本身、a/nested/x.py、空排除列表分别覆盖目录本身、后代和默认行为。
4改实现按路径分段比较祖先关系让a和ab在段级别不同。
5重新验证功能断言与相关回归同时运行测试通过必须绑定修改后的版本。

把过程连起来。“有测试”不够,测试需要能区分正确语义与一个看起来合理的错误实现。

边界与反例。本例仅为路径段语义;真实跨平台路径还涉及分隔符、规范化、符号链接和安全边界。

依据与适用范围:[DERIVE]。示例输入和场景由本书明确设定。

课后自检

自检 1

函数永远返回true能通过一个正向测试,说明什么?

查看参考答案收起参考答案
说明测试缺少区分错误实现的反例,不说明实现正确。应增加不应排除的路径等负向情况。
自检 2

代码又改了,但测试未重跑,能沿用之前全绿结论吗?

查看参考答案收起参考答案
不能作为当前版本已验证的证明。需要重跑受影响检查或明确验证范围与版本。

机制依据:[REVIEW][SWEBENCH][EVALS]。本节数值与情景除另注外均为原创教学示例;来源不代替中文讲解。

记录保存在本机浏览器。

输入关键词即可检索。

↑ ↓ 选择 Enter 打开Esc 关闭 · 仅本地搜索

阅读设置

阅读设置仅保存在本机浏览器,不上传任何数据。