Foundry测试进阶教程:不变量、handler 与高阶 cheatcodes 实战
当你能熟练写单元测试与简单 fuzz 后,下一步要面对的就是更接近真实业务的测试场景:不变量、状态机、外部依赖模拟与事故重放。本文围绕 Foundry测试进阶教程的核心议题,把这些主题串成一条系统训练路径。基础学习路径请见 Foundry测试入门指南。
一、不变量测试的核心思想
不变量测试关注「无论操作顺序如何,某条件始终成立」:
- 例:池子的资产总和不应该被某种交易组合掏空
- 例:每个用户的余额之和等于合约总余额
- 例:抵押率始终高于清算阈值
这种性质用传统单测难以覆盖,因为操作组合的数量呈指数级增长。Foundry 通过自动遍历方法组合解决了这个问题。
二、handler 模式
handler 是不变量测试的设计核心:
- 写一个 handler 合约,封装真实用户可能调用的方法
- 在 handler 内做 bound、过滤等预处理
- 在测试合约中用
targetContract(handler)注册 - Foundry 会随机调用 handler 的方法,组合出长链动作
这种模式比 raw fuzz 更可控,覆盖率也更精准。详细写法可参考 Foundry测试最佳实践。
三、高阶 cheatcodes
进阶阶段常用:
vm.snapshot()/vm.revertTo():快照与回滚状态vm.mockCall/vm.mockCallRevert:模拟外部合约返回vm.recordLogs与vm.getRecordedLogs:捕获并断言事件流vm.startBroadcast/vm.stopBroadcast:脚本中分段广播vm.parseJson*:从文件读取 JSON 参数
这些 cheatcodes 让测试可以构造任意复杂的链上场景,是 Foundry测试官方文档 中重点章节的内容。
四、分叉测试与事故重放
复杂的进阶用法:
- 用 createSelectFork 拉取主网或币安智能链特定区块
- 在分叉环境中重放真实交易
- 修改某个参数后再次重放,验证不同决策的影响
- 配合 cast trace 看完整调用链
这种能力对于做协议升级评估、安全事故复盘极其重要,是 Foundry测试漏洞案例 中频繁使用的工具。
五、Gas 优化驱动的测试
进阶测试也是 Gas 优化的最佳工具:
forge test --gas-report列出每函数 Gasforge snapshot把 Gas 快照写入文件,便于版本对比- 在 CI 中校验 Gas 不应高于上一版本
- 配合 hardhat-tracer 或 Tenderly 进一步剖析高 Gas 路径
六、与监控系统的协作
进阶项目把测试与监控打通:
- 每次主网出现异常,自动 fork 出事故区块跑测试
- 测试用例库不断累积,形成「事故案例库」
- 新功能上线前必跑历史事故套件,防止旧 bug 复现
这种做法把测试从「保证当前正确」升级为「保证历史不重演」,是 Foundry测试完整教程 中介绍的高阶模式。
七、与 Hardhat 部署联动
进阶团队通常组合使用:
- Foundry 跑不变量、fuzz、分叉测试
- Hardhat 跑部署脚本与跨链编排
- CI 中并行执行两者,结果汇总到同一报告
这种组合在大型协议中已成主流,性能与开发体验都达到平衡。
八、训练路径
建议训练顺序:
- 第 1 周:把所有现有测试改写为 Foundry 风格
- 第 2 周:为核心合约写 fuzz 测试
- 第 3 周:设计 handler 与不变量
- 第 4 周:建立分叉测试与事故案例库
- 第 5 周:把上述测试集成进 CI,配置 Gas 阈值
按这个节奏走完,你的测试能力会真正进入工程化阶段。Foundry 测试的上限非常高,关键在于持续把真实世界的复杂性纳入测试范畴。