Foundry测试是什么:以纯 Solidity 编写的下一代链上测试框架
如果你刚接触 Solidity 工具链,可能听说过 Foundry 测试比 Hardhat 测试快得多,但具体快在哪、怎么用还不清楚。本文围绕「Foundry测试是什么」这个问题展开,用尽量通俗的语言讲清楚它的核心理念与适用场景。系统入门可以接着读 Foundry测试入门指南。
一、Foundry 测试的核心理念
Foundry 测试与 Hardhat 测试最大的不同在于语言:
- Hardhat 用 TypeScript/JavaScript 写测试,跑在 Node 进程中
- Foundry 用 Solidity 写测试,跑在原生 Rust 实现的 EVM 中
这种设计意味着测试代码与被测合约共享同一套类型系统,调用合约方法就像调用本地函数一样直接,省去了中间序列化的开销。
二、速度优势的来源
Foundry 的极速来自几个方面:
- 原生 Rust EVM 实现,性能远超 JS 模拟
- 测试函数并行执行,CPU 多核充分利用
- fuzz 用例缓存,失败用例下次优先重放
- 编译产物增量构建,改一处只重编一处
实际项目中,Hardhat 跑十秒的测试 Foundry 通常一两秒内跑完,差异极其显著。
三、cheatcodes 提供的能力
纯 Solidity 测试有一个天然问题:无法控制运行环境(时间、账户、余额)。Foundry 通过「作弊码」解决:
vm.prank模拟任意发送者vm.warp跳到任意时间vm.deal给地址发钱vm.expectRevert/vm.expectEmit断言异常与事件vm.mockCall模拟外部依赖返回值
这套作弊码让测试覆盖几乎任何场景,是 Foundry 与传统框架体验差异最大的地方。详细列表参考 Foundry测试官方文档。
四、fuzz 与不变量测试
Foundry 把 fuzz 做成了一等公民:
- 测试函数声明参数即开启 fuzz
- 自动生成大量随机输入
- 失败用例被缓存
- 可以与 invariant testing 结合做不变量校验
这种能力极适合 DeFi 合约:例如「无论以何种顺序调用 deposit/withdraw,资金总和应保持不变」这样的不变量,传统单测难以覆盖,fuzz 几秒就能跑数千组组合。
五、分叉测试与真实链状态
vm.createSelectFork 让本地测试可以在真实链状态下运行:
- 拉取主网或币安智能链特定区块的状态
- 直接与真实合约交互
- 复现线上事故、验证升级前后行为
这种能力在 Foundry测试漏洞案例 复盘中是核心工具,能精准还原事故现场。
六、适合的场景
Foundry 测试特别适合:
- 纯 Solidity 项目,团队不想引入 JS 栈
- 需要大量 fuzz 覆盖的金融合约
- 需要在 CI 中快速跑大量测试用例
- 复现链上事故、做精细 Gas 优化
不太适合:
- 复杂的 TypeScript 业务测试(涉及前端/链下逻辑)
- 团队完全没有 Solidity 测试经验
- 与现有大型 Hardhat 项目深度耦合
七、与 Hardhat 的关系
Foundry 与 Hardhat 不是非此即彼:
- 用 Foundry 跑核心合约测试
- 用 Hardhat 跑部署脚本与前端集成测试
- 两者共享 ABI 与 deployments 目录
这种组合在大型项目中越来越普遍,Foundry测试与Hardhat比较 等关键字下有更详细的对比。
八、币安智能链上的适用性
BNB Chain 与以太坊主网类似,Foundry 测试可以无缝运行,分叉测试只需在 foundry.toml 中加入 bsc 节点 URL。社区 Foundry测试中文文档 中有详细配置范例。Foundry 测试的本质是把测试做成开发的一部分,而不是开发完成后的附加工序。理解了这一点,就理解了为什么这么多新项目把 Foundry 作为首选测试框架。