用途
本技能是一项基于性质的测试(Property-Based Testing,PBT)指导,用于在开发过程中主动识别适合采用 PBT 的代码模式,从而提供比传统示例测试更强的覆盖。适用对象涵盖多种编程语言以及智能合约。
主要能力
技能能够自动检测以下模式并建议使用 PBT:
- 序列化对:
encode/decode、serialize/deserialize、toJSON/fromJSON、pack/unpack - 解析器:URL 解析、配置解析、协议解析、字符串到结构化数据
- 归一化:
normalize、sanitize、clean、canonicalize、format - 验证器:
is_valid、validate、check_*(尤其配合归一化器) - 数据结构:带
add/remove/get操作的自定义集合 - 数学/算法:纯函数、排序、排序规则、比较器
- 智能合约:Solidity/Vyper 合约、代币操作、状态不变量、访问控制
按模式划分的优先级:encode/decode 对(往返,高)、纯函数(多重,高)、验证器(归一化后有效,中)、排序/排序(幂等 + 排序,中)、归一化(幂等,中)、构建器/工厂(输出不变量,低)、智能合约(状态不变量,高)。
使用方式
技能根据当前任务提供决策树引导:
- 编写新测试:阅读
{baseDir}/references/generating.md(测试生成模式与示例),若输入生成复杂则再阅读{baseDir}/references/strategies.md - 设计新功能:阅读
{baseDir}/references/design.md(性质驱动开发方法) - 代码难以测试(混合 I/O、缺少逆操作):阅读
{baseDir}/references/refactoring.md(可测试性重构模式) - 审查现有 PBT 测试:阅读
{baseDir}/references/reviewing.md(质量检查清单与反模式) - 测试失败需解读:阅读
{baseDir}/references/interpreting-failures.md(失败分析与缺陷分类) - 需要库参考:阅读
{baseDir}/references/libraries.md(按语言分类的 PBT 库,含智能合约工具)
技能还提供如何建议 PBT 的话术:当检测到高价值模式时,以选项形式向用户提出;若代码库已使用 PBT 库(如 Hypothesis、fast-check、proptest、Echidna),则更直接地说明将编写基于性质的测试;若用户拒绝,则编写良好的示例测试,不再追问。
适用场景
- 序列化/解析/归一化/验证器等存在复杂输入域的代码
- 纯函数、排序算法、比较器
- 自定义数据结构
- 智能合约的状态不变量与访问控制
- 单元/组件测试层面
限制
技能明确指出不适用于以下场景:
- 无转换逻辑的简单 CRUD 操作
- 一次性脚本或弃用代码
- 无法隔离的副作用代码(网络调用、数据库写入)
- 具体示例用例足够且边界情况已知的测试
- 集成测试或端到端测试(PBT 最适合单元/组件测试)
- UI/展示逻辑
- 需求易变的原型阶段
- 用户明确要求仅使用示例测试
性质目录(快速参考)
| 性质 | 公式 | 使用时机 |
|---|---|---|
| 往返 | decode(encode(x)) == x |
序列化、转换对 |
| 幂等性 | f(f(x)) == f(x) |
归一化、格式化、排序 |
| 不变量 | 变换前后性质保持 | 任意变换 |
| 交换律 | f(a, b) == f(b, a) |
二元/集合操作 |
| 结合律 | f(f(a,b), c) == f(a, f(b,c)) |
组合操作 |
| 恒等 | f(x, identity) == x |
含中性元素的操作 |
| 逆操作 | f(g(x)) == x |
加密/解密、压缩/解压 |
| 预言机 | new_impl(x) == reference(x) |
优化、重构 |
| 易验证 | is_sorted(sort(x)) |
复杂算法 |
| 无异常 | 对有效输入不崩溃 | 基线性质 |
强度层级(从弱到强):无异常 → 类型保持 → 不变量 → 幂等性 → 往返。
红旗警示
- 推荐琐碎的 getter/setter
- 缺少配对操作(有 encode 无 decode)
- 忽略类型提示(类型良好 = 更易测试)
- 向用户提供过多候选(限制在 5-10 个)
- 用户拒绝后仍强行推荐
应拒绝的合理化借口
- “示例测试已经足够”——若涉及序列化/解析/归一化,PBT 能找到示例遗漏的边界情况
- “函数很简单”——简单函数搭配复杂输入域(字符串、浮点数、嵌套结构)最能从 PBT 受益
- “我们没时间”——PBT 测试通常比全面的示例套件更短
- “写生成器太难”——多数 PBT 库有优秀的内置策略,很少需要自定义生成器
- “测试失败所以是 bug”——失败需要验证
- “没崩溃就说明能用”——“无异常”是最弱的性质,应始终追求更强的保证
参考资料与许可
本技能引用上游文档:Trail of Bits 的 property-based-testing 技能(修订号 5c15f4f5644b4bd3d48882a802a7232d501852b6),许可为 CC-BY-SA-4.0。作者声明见 paperclipai/companies 仓库。资料未提供收费、价格、平台或具体安装命令等信息。
引用文档
以下为作者声明的引用来源,保留指定版本、署名和许可。
- trailofbits/skills/plugins/property-based-testing/skills/property-based-testing/SKILL.md — 署名:Trail of Bits;许可:CC-BY-SA-4.0;版本:
5c15f4f5644b4bd3d48882a802a7232d501852b6。