该技能的核心问题是:测试套件显示绿色(全部通过),但这能否作为有效证据?资料指出,多种陷阱可以产生与健康套件相同的绿色结果,但计数、跳过项或加载产物可能不同,因此需要检查证据本身,追问每个测试在何种契约违反下会变红。
主要检验方向
资料列出了多类导致“假绿”的情形,可归纳为以下几个层面。
测试从未运行
最彻底的假绿。共同缓解方式是:不再把零退出码当作信号,而是断言实际执行的数量。
- 零收集不等于零失败:选择器可能匹配不到任何测试,而某些运行器或包装配置仍以零退出。必须验证被选择和被执行的集合,而非绿色摘要或退出状态。门禁应断言非零的收集并执行计数,且每个被选测试都通过,而非仅仅“未失败”。
- 快速失败运行器截断结果:当运行器在首个失败处停止,其摘要描述的是停止点,而非整个套件。“1 failed”不构成上界,因为其余测试从未执行。“N skipped”意味着 N 个测试未运行,这是以通过术语报告的覆盖缺口。引用计数前应确认运行器是否完整运行,报告被执行数与收集数,并在提前停止时说明“首个失败”而非“一个失败”。
发现机制不一致
套件通常有多个注册表:磁盘文件、清单、构建系统组件列表、包导出列表、分片配置。某测试存在于部分注册表而缺失于其他注册表时,可能编译通过、手动调用通过,但从未被调度。应编写元测试,将注册表与文件系统及其他注册表对账,当任何测试源无法从规范入口到达时失败。
常见单注册表情形是清单与目录并排签入,如 ASDF :components、CMake 测试列表、CI YAML 测试矩阵、显式 init 导出列表。目录中放入文件但清单未收录时,手动调用可单独编译通过,只有规范入口的沉默揭示缺口。应将清单与同一树的目录列表做差,断言差集为空或显式有意(排除列表签入在清单旁)。
两种命名约定共用一个 glob 时,运行器只匹配一种,静默忽略另一种的文件,而配置在审查中看起来合理。应比较运行器报告的测试文件数与磁盘计数,或通过 lint 规则强制单一约定。
生成进程结果未断言
集成测试工具启动二进制或 fork 工作进程后检查副作用,若进程在做事之前崩溃,只要所检查副作用可缺失或预先存在,测试仍报告成功。应断言每个生成进程的退出状态和每个工作池的完成计数,再断言副作用。非零状态、panic 计数大于零、完成计数低于派发计数,本身即为测试失败。
注册冲突删除测试
具有全局名称键注册表的框架在重复注册同名测试时会替换已有注册,从而静默删除一个测试而非报告冲突。来源包括:共享辅助文件既作为依赖加载又被递归加载器作为独立文件拾取;迁移到表驱动生成器时遗留手写用例。辅助文件不应定义测试;转换后应删除被替换的用例;生成名称应带命名空间前缀;断言注册后计数等于预期用例数。
断言不可能失败
这类测试在审查中看起来真实,在覆盖率报告中计数为已覆盖行。
- 命名断言拒绝的错误结果:接受集合覆盖系统所有可能输出的断言是重言式。常见形式是析取:断言结果为空值或良构对象,而二者穷尽返回类型。应替换为精确预期结果。回归测试应通过在修复前代码上失败来命名其错误结果。
- 不得调用被测对象计算预期值:通过调用被测系统推导预期值,在纯函数时断言恒真,有状态时可能不稳定。预期值应基于规范、夹具或先前捕获的产物。
- 刺激不得满足断言:当输入通道在输出通道可见时,刺激而非系统响应可满足断言。应禁用回显、在刺激前快照输出并只搜索刺激后增量、使用编码或拆分输入发出标记、携带仅输出随机数并编码退出状态。
- 编号兄弟项的子串匹配:对含序号的渲染文本做子串断言会匹配其编号兄弟项。应解析为块,断言块数及首末块;不可避免时用不能出现在兄弟标识符内的定界符锚定。
- 观察不得移动度量:探测缓存、计数器或限流组件本身可能注册为访问。应通过无副作用访问器读取,或在动作前快照并断言增量。
夹具移除了被测对象
测试运行且断言有意义,但检查的是设置完成的工作。
- 存在性探针被自身替身满足:任何“依赖是否可用”检查会被替换该依赖的替身满足。应通过仅真实组件能产生的行为证明可用性,不要用名称探针;不要用捕获所有异常的边界包裹吞掉参数数量或签名错误;替身签名应与真实组件对齐。
- 部分模块替身抹除值导出:部分模块替换通常重新声明函数而省略其他导出,非函数导出解析为 undefined,导致验证代码将每个输入归类为无效并返回空结果。应重新导出消费者读取的每个符号。
- 种子只建立前置条件,不建立被测对象:当种子同时创建测试声称验证的产物时,测试断言的是产品自身可能无法到达的状态。种子可建立世界、角色和库存前置条件;被测转换应通过真实用户驱动的同一接口执行。
- 夹具错过守卫导致空操作:路径以守卫子句开头时,夹具不满足守卫会使整个交互变成空操作。应枚举路径上的守卫并显式满足每个;集成测试失败时先确认代码路径确实运行。
- 在任何注册前重定向所有持久化路径:只重定向明显持久化路径的测试工具会让其他路径指向真实用户状态。应在任何代码路径加载或注册前,将每个持久化路径绑定到每次运行的临时位置,并添加套件级断言确认真实用户文件未变。
无人能触发的守卫
- 证明守卫会触发:无人越过的安全控制是惰性的,且无人报告。行覆盖和分支覆盖完全满足,而有趣分支在实践中不可达。应编写驱动每个守卫触发的测试;阈值优先相对测量基线而非绝对常量;测量应放在其馈送的门禁之外。
- 删除不可能分支而非测试它:严格分支覆盖下,不可达防御分支有三种处理:构造不可能输入的测试、用 pragma 抑制、删除。第一种最差。判别标准:回退行为是否用户可见,或因上游不变量保证输入而不可达。测试前者,删除后者并断言不变量。信任边界的失败关闭检查应保留并测试拒绝。
失败被吞掉
清理代码是常见元凶:它在成功和失败路径都运行,并被写成不会失败的样子。
使用方式
资料未提供具体安装命令、代码示例或操作步骤,因此暂未提供。该技能以检查清单和原则形式呈现,使用时应逐项对照上述情形审查测试套件。
适用场景
适用于测试套件显示绿色但价值存疑时,包括怀疑假绿、零测试收集、空断言、死守卫、模拟对象使代码失去真实检验等情形。
限制
资料未说明平台兼容性、收费模式、价格等具体信息,暂未提供。该技能假定测试已存在,只追问绿色结果是否可信;测试设计本身(单元/集成/e2e 划分、arrange-act-assert、替身选择、接缝位置、夹具、结算屏障、覆盖率作为指标)属于 testing-patterns,不在本技能范围内。