用途
本技能是一条关于测试的原则,名称为「测试行为而非实现」(test behavior not implementation)。它用于判断一个测试是否应当保留:测试应当像调用者那样驱动被测代码,并把调用者所能观察到的结果,与测试中字面写出的值进行比较。
原则的核心判断是:一个任何缺陷都无法让它变红的测试,只会消耗运行时间和评审注意力,并不守护任何东西。
适用时机
当某个测试的断言没有 plainly 地把被测对象的输出与一个字面值进行比较时,适用本原则。
该原则所处理的接缝,是实现步骤 3 所命名的那个接缝,即接口;本原则管的是当测试站在该接缝处时,断言应当读到什么。
主要判断标准
断言代码调用了哪些调用、或重复代码持有的某个常量,都没有观察到行为,因此都不算对行为的测试。
在保留一个测试之前,设想把它导入的每个函数都换成一个什么都不返回的版本。如果在该替换下测试依然保持绿色,那么这个测试没有观察到任何东西:重写它的断言,或删除它。
以下断言会通不过这一替换检验:
- 只检查某个值存在、为真、具有某种类型、没有抛异常、或大于零。
- 完全没有断言的测试。
- 只断言某个 mock 被调用过或没被调用过。
- 只断言结果为空、缺失,或与某一个错误值不相等。
- 期望值由被测代码自身产生(被测对象与自己的输出比较,或把解析出的字段与生成它的构建器比较)。
- 断言重复一个手动维护的常量、配置默认值、表格行或提示词字符串。
- 断言针对测试或其 setup 构造的数据,而测试体内从未调用被测对象。
修复方式
- 在测试体内,以一个具体输入运行被测对象,并比较它的字面输出或可见效果。例如,把标题交给 slug 生成器,得到精确的 slug。
- 缺失应当与其反面并列测试:同一个测试同时断言第二个输入所产生的存在情况。
- 常量应通过在一个输入上运行读取它的代码来覆盖,绝不通过重述它的值来覆盖。
- mock 应依据它收到的载荷或它留下的状态来评判,绝不依据它是否运行过来评判。
- 没有可用断言可写的测试,删除。
例外与边界
仍然可以通过的测试包括:检查表中行与行之间关系的测试(例如两张表共享的键,或存在的父行),以及类型检查器在编译期执行的检查。
本原则的边界在于:它决定一个测试是否保留;实现步骤的红线规则仍然决定一个切片是否完成,而被保留的测试必须同时满足两者。哪些失败模式需要测试、一次改动应得多少测试,仍由实现步骤关于列出切片失败模式的规则决定。
限制
该资料未提供关于收费、价格、平台支持、安装步骤或更多使用示例的信息。