关于 principle-test-behavior-not-implementation
Test Behavior, Not Implementation 是面向开发者的测试原则,强调验证可观察的契约,而非内部结构。它用两项检查判断测试是否应保留或修改:能否发现行为破坏,以及内部重构后能否继续通过。
主要功能
- 01让测试聚焦可观察行为
- 02检查测试能否发现行为破坏
- 03检查测试能否经受内部重构
- 04根据需求推导预期结果
- 05覆盖接口层面的不变量
适用场景
- 01审查测试是否验证用户可见的契约
- 02修改依赖私有辅助函数的测试
- 03检查断言是否过于宽松或过度限定
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ backnotprop/ pstack --skill principle-test-behavior-not-implementation安装后在 Claude Code 中输入/principle-test-behavior-not-implementation确认已加载。
详细介绍
测试行为,而非实现
测试是对代码为用户做了什么的判断:这些用户可以是调用方、终端用户,也可以是其他服务。行为是这些用户通过所用接口能够观察到的内容,包括返回值、错误、可读回的状态,以及代码外部系统上的效果,例如发送请求、写入一行数据或发出消息。实现则是用户无法观察到的内容:私有辅助函数、内部调用顺序、中间数据,以及实际完成工作的内部协作者。
用两种假想的修改来审视每项测试:
- 破坏行为。 让代码返回错误值、跳过某项效果,或将某项效果执行两次。如果测试仍然通过,它就无法证明任何事情。常见原因包括:断言比契约宽松、预期值由被测代码计算、重复写出一个常量或提示词字符串,却从未运行读取它的代码,以及断言测试自己构造的数据。
- 更改内部实现。 保持所有可观察结果不变,只调整底层代码结构。如果测试因此失败,它就依赖于实现细节。每次重构都得重写,而且仍然抓不到任何 bug。
保留能捕获第一种修改且能经受第二种修改的测试。重写或删除其余测试。要同时做到这两点,需通过用户使用的接口驱动代码,并提供具体输入。依据需求推导预期值,而不是运行代码得出。对契约承诺的内容进行断言,不多不少。
判断依据是契约,而非断言的形式。当承诺是“空购物车绝不会扣款”时,断言支付客户端没有被调用就是对行为的验证。再配上一种确实发生扣款的情况,这样测试才能证明自己能够检测到调用。模拟的外部服务收到的负载属于行为,因为该服务可以观察到它。对内部辅助函数的调用属于实现,因为没有用户能看到它。没有记录匹配时,空列表就是准确的答案;如果测试只需要某种结果,空列表检查就毫无意义。精确的错误消息会将测试绑定到调用方不会读取的措辞。调用方据以分支处理的错误类型才是契约。
测试也可以验证不涉及调用的不变量,例如两个表中都必须存在某个键,或进行编译时类型检查。不变量就是行为。
评论
支持 Markdown