ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Foundry 测试套件全解析:深入 testdata 测试目录结构与核心测试用例

Foundry 测试套件全解析:深入 testdata 测试目录结构与核心测试用例 Foundry 测试套件全解析深入 testdata 测试目录结构与核心测试用例【免费下载链接】foundryFoundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.项目地址: https://gitcode.com/GitHub_Trending/fo/foundryFoundryRust 实现的以太坊应用开发工具包将自身所有关键能力——基础运行、作弊码cheatcodes、分叉、模糊测试、跟踪等——沉淀为一套自测体系集中存放在仓库的 testdata 目录下。本文以 testdata/README.md 为骨架结合 testdata/foundry.toml 与真实测试源码完整梳理 Foundry 测试套件的目录结构、组织约定与代表性用例帮助你快速掌握如何阅读、运行和扩展这套测试资产进而理解 Foundry 内部各模块的验收标准。一、测试套件概览Foundry 如何自证其成testdata/README.md开宗明义这是一套测试 Foundry 不同方面different aspects的测试套件。换句话说Foundry 不仅用它来验证自己的合约测试框架还用它来测试forge、anvil、cast等组件在不同场景下的行为是否符合预期。该目录既是回归测试的护城河也是新开发者理解 Foundry 功能边界的活教材。从 AGENTS.md 的贡献指南可以看到它的地位新增一个作弊码时要求开发者在testdata/default/cheats/下添加集成测试docs/dev/cheatcodes.md 同样把testdata/default/cheats/作为作弊码开发流程的必由之路。因此这套测试数据是 Foundry 开发流程中行为契约的一部分。1.1 测试目录的布局原则README 列出的核心子目录均以相对路径形式指向testdata/default/下core测试 Foundry 的基础能力logs测试 Foundry 的日志能力cheats测试 Foundry 作弊码fuzz测试 Foundry 模糊测试器trace测试 Foundry 跟踪器fork测试 Foundry 的分叉能力说明README 描述的是套件的完整逻辑分类。在当前仓库快照中testdata/default/实际包含cheats/、core/、fork/、fs/、inline/、linking/、repros/、spec/、vyper/等子目录其中cheats/体量最大超过 100 个测试文件。部分分类如 logs、fuzz、trace的用例可能随版本迭代被合并到其他目录或由crates/evm/fuzz、crates/evm/traces等 crate 的单元测试承接本文以快照中真实存在的文件为准展开。1.2 目录之外的配套资产测试套件不止有.t.sol文件还包括testdata/foundry.toml整套测试的 Foundry 配置testdata/utils/Test.sol 与 testdata/utils/Vm.sol测试基类与作弊码接口声明Vm接口被大量测试以vm.xxx形式引用testdata/src 下的Counter.vy、ICounter.vyiVyper 合约测试资产testdata/multi-version 与 testdata/paris多编译器版本与不同 EVM 版本的专项测试目录testdata/fixturesJSON、TOML、RPC 等数据夹具供cheats/Json.t.sol、cheats/Toml.t.sol等用例读取。二、测试套件的运行环境foundry.toml 逐项解读testdata/README.md没有直接给出配置但套件能否跑通完全取决于 testdata/foundry.toml。这份配置本身就是一份高价值的实战参考[profile.default] src src test ./ remappings [cheats/default/cheats/] optimizer true optimizer_runs 200 via_ir false ignored_error_codes [ 1878, # SPDX license identifier not provided 2018, # Function state mutability can be restricted 2072, # Unused local variable 2424, # Natspec memory-safe-assembly special comment deprecated 2519, # This declaration shadows an existing declaration 3860, # Contract init code size exceeds limit 5159, # Selfdestruct has been deprecated 5574, # Contract code size exceeds limit 5667, # Unused function parameter 9207, # transfer is deprecated ] extra_output [storageLayout]关键点test ./把整个testdata目录作为测试源码根因此所有*.t.sol都会被forge test扫描remappings为测试中的cheats/...导入提供路径映射ignored_error_codes显式屏蔽了一批编译器告警如 1878 缺失 SPDX、3860 合约初始化代码超限、5159 selfdestruct 弃用等说明测试用例刻意覆盖正常项目不会触发的边界写法测试套件本身也必须容忍这些告警extra_output [storageLayout]要求编译器输出存储布局这是cheats/StateDiffStorageLayout.t.sol等用例能校验存储槽位的前提。配置还包含两个测试专用的编译器 profile用于验证 forge 的 profile 选择机制additional_compiler_profiles [ # paris - EVM version paris for testing profile selection { name paris, evm_version paris }, # no-metadata - stable bytecode for cross-platform multi-version tests { name no-metadata, bytecode_hash None }, ] compilation_restrictions [ # paris - files in paris/ directory use paris EVM version { paths paris/**, evm_version paris }, # Keep multi-version bytecode stable across platforms while preserving the encoded solc version. { paths multi-version/**, bytecode_hash None }, ]compilation_restrictions让不同路径使用不同编译参数paris/**强制 EVM 版本 parismulti-version/**关闭元数据哈希以换取跨平台稳定字节码这正是 testdata/paris 与 testdata/multi-version 目录能被独立验证的机制。安全与网络相关配置同样值得注意ffi true fs_permissions [ { access read-write, path out/ }, { access read-write, path fixtures/ }, ] verbosity 3 prompt_timeout 0 [profile.default.rpc_storage_caching] chains all endpoints all [profile.default.invariant] depth 15ffi true允许测试调用外部命令cheats/Ffi.t.sol、cheats/TryFfi.sol依赖它fs_permissions只向out/与fixtures/开放读写其余路径保持只读fs/ReadOnly.sol、fs/Disabled.t.sol正是为了验证文件系统权限边界verbosity 3提高默认日志级别prompt_timeout 0用于自动化场景不等待交互输入rpc_storage_caching开启全链全端点的 RPC 存储缓存invariant.depth 15设定不变量测试的调用深度上限。最后是 RPC 端点配置多数通过环境变量注入由cargo (nex)test运行前填充的.env提供同时包含若干公共端点[rpc_endpoints] mainnet ${RPC_MAINNET} sepolia ${RPC_SEPOLIA} optimism ${RPC_OPTIMISM} base ${RPC_BASE} arbitrum ${RPC_ARBITRUM} avaxTestnet https://api.avax-test.network/ext/bc/C/rpc moonbeam https://moonbeam.api.onfinality.io/public polkadotTestnet https://eth-rpc-testnet.polkadot.io这些端点服务于 testdata/default/fork 以及cheats/Fork.t.sol、cheats/RpcUrls.t.sol等分叉类用例。三、核心目录逐一拆解从代码验证功能边界3.1core/Foundry 基础行为契约testdata/default/core 存放验证 Foundry 测试执行模型本身的用例SetupConsistency.t.sol验证setUp()在每个测试函数执行前都被重新执行状态不跨用例泄漏——testAdd与testMultiply都断言result 0证明每个用例都从干净的setUp状态开始Abstract.t.sol抽象测试基类模式AbstractTest继承AbstractTestBase并在setUp中实例化 fixture验证继承场景下setUp的调用链Reverting.t.sol用vm.expectRevert(should revert here)断言下一个调用必定回滚注释中的/// forge-config: default.allow_internal_expect_revert true展示了在 Solidity 注释中内联覆盖 forge 配置的写法BadSigAfterInvariant.t.sol、ContractEnvironment.t.sol分别覆盖不变量测试之后非法签名的处理与合约级测试环境语义。这类用例验证的是测试框架自身的语义属于 Foundry 区别于普通应用测试的最基础层次。3.2cheats/作弊码的完整验收场testdata/default/cheats 是套件中体量最大、覆盖面最广的目录几乎每个作弊码都有对应测试文件。从文件命名即可窥见功能全景Warp时间、Roll区块号、Prank身份模拟、ExpectRevert预期回滚、ExpectEmit预期事件、Deal/Store/Load状态操纵、MockCall/MockCalls调用模拟、Sign/Ec/Ed25519密码学、Json/Toml序列化、Ffi外部命令、Record/RecordLogs追踪、Broadcast广播、Fork分叉、Sleep、Random*系列确定性随机等。以 Warp.t.sol 为例它同时给出固定值与模糊化两种测试写法function testWarp() public { vm.warp(10); assertEq(vm.getBlockTimestamp(), 10, warp failed); } function testWarpFuzzed(uint32 jump) public { uint256 pre vm.getBlockTimestamp(); vm.warp(vm.getBlockTimestamp() jump); assertEq(vm.getBlockTimestamp(), pre jump, warp failed); }testWarpFuzzed接受模糊输入uint32 jump验证 warp 对任意偏移都满足新时间戳 旧时间戳 jump这正是测试既覆盖正常路径又覆盖随机边界的典型模式。Prank.t.sol 则是作弊码测试的深度范本覆盖了vm.prank(sender)/vm.prank(sender, origin)单次模拟与vm.startPrank/vm.stopPrank持续模拟对构造函数的 pranktestPrankConstructorSender嵌套调用、嵌套 prank 的深度语义文件内甚至用 ASCII 时序图注释说明了startPrank未停止时的深度行为delegatecall 场景下msg.sender的模拟与安全限制对 EOA 发起 prank 后的 delegatecall 会报错vm.prank: cannot prank delegate call from an EOAprank 被覆盖/未消费时的保护逻辑vm.startPrank: cannot overwrite a prank until it is applied at least once。ExpectRevert.t.sol 完整演示了vm.expectRevert的全部重载形态字符串消息、Error(string)ABI 编码前缀、内置Panic(uint256)如 0x11 算术下溢、自定义错误选择器、嵌套调用回滚、构造器回滚、无理由revert()、EVM 错误EvmError: OutOfGas、vm.expectRevert()无参任意回滚以及count计数重载预期接下来的 N 次调用回滚。更精细的部分还包含reverter 地址参数限定由哪个合约触发回滚、vm.expectPartialRevert(selector)部分匹配以及对 CREATE/CREATE2 部署回滚时将要部署地址作为 reverter 的验证用例中通过vm.computeCreateAddress/vm.computeCreate2Address计算期望地址。这些用例同时也服务于 crates/cheatcodes 的实现回归例如对 issue 14613顶层 CREATE 回滚时 reverter 参数被静默忽略的回归覆盖。此外Json.t.sol与Toml.t.sol的头部注释展示了利用forge eip712子命令配合 remapping 生成结构化测试数据的技巧而dumpState.t.sol、loadAllocs.t.sol、StateDiff*系列则覆盖状态转储与状态差异校验——这些能力是anvil状态管理功能正确性的重要验证来源。3.3fork/分叉与多链测试testdata/default/fork 验证 Foundry 的状态分叉能力LaunchFork.t.sol在测试中动态创建分叉ForkSame_1.t.sol 与 ForkSame_2.t.sol两个文件协同验证多次分叉同一链时的状态一致性DssExecLib.sol以真实复杂的 MakerDAO DssExecLib 合约为对象做分叉集成测试检验分叉环境下复杂合约的加载与执行。分叉测试依赖 testdata/foundry.toml 中的 RPC 端点与环境变量RPC_MAINNET、RPC_SEPOLIA等因此这类用例通常在配置了对应密钥的 CI/本地环境中运行。3.4fs/、inline/、linking/、repros/、spec/、vyper/专项边界fs文件系统权限边界——Disabled.t.sol验证禁止读写时被正确拦截ReadOnly.sol验证只读模式下写操作被拒绝inline内联配置——FuzzInlineConf.t.sol与InvariantInlineConf.t.sol通过/// forge-config:注释在源码内覆盖模糊测试与不变量测试配置linking库链接专项含cycle/链接环、duplicate/重复链接、nested/嵌套链接、profile_nested/、samefile_union/、simple/等子场景直接对应 crates/linking 的实现边界repros回归测试仓库——以Issue10302.t.sol、Issue14212.t.sol等 GitHub issue 编号命名的用例记录历史上修复过的缺陷防止复发spec规范/接口测试vyperVyper 合约编译与测试与 testdata/src/Counter.vy 配套验证 Foundry 对 Vyper 语言的支持。3.5paris/、multi-version/、fixtures/跨版本与数据夹具testdata/paris仅使用 paris EVM 版本编译运行验证 profile 选择机制配置见前文compilation_restrictionstestdata/multi-version以bytecode_hash None保证跨平台字节码稳定验证多版本 solc 兼容性testdata/fixturesJson/、Toml/、Dir/、File/、GetCode/、Rpc/等数据目录以及broadcast.log.json、broadcast.sensitive.log.json广播日志样例供对应作弊码用例与cast命令测试读取。四、如何运行与扩展这套测试套件4.1 运行方式测试套件本质是一组标准 Foundry 项目资产可在仓库根目录使用 forge 运行。由于 testdata/foundry.toml 中test ./最直接的方式是在testdata/目录下执行cd testdata forge test分叉类用例需要 RPC 环境变量RPC_MAINNET、RPC_SEPOLIA等见 testdata/foundry.toml且 RPC 端点可能因网络状况而异不含 RPC 的用例如cheats/Warp.t.sol、core/SetupConsistency.t.sol可独立运行例如forge test --match-contract WarpTest -vv仓库 CI 通过cargo (nex)test运行前会填充.env中的 RPC 变量说明这套套件在 Foundry 自身的持续集成中作为端到端集成测试被执行。4.2 扩展约定新用例怎么写结合 AGENTS.md 与 docs/dev/cheatcodes.md 的指引新增作弊码用例的固定流程是在 testdata/default/cheats/ 新增Xxx.t.sol继承Test基类import utils/Test.sol对应 testdata/utils/Test.sol以test开头命名测试函数用vm.*调用被测试的作弊码同时更新cheats/Vm.sol接口该文件被 testdata/foundry.toml 中的[fmt] ignore排除格式化以保持其自动生成的形态。新测试文件一旦落入testdata/default/cheats/就会被forge test自动发现因此扩展成本极低。五、测试套件与源码模块的对应关系从源码结构看测试资产与实现模块存在清晰的映射关系可据此定位实现与阅读入口测试目录主要验证对象相关实现default/cheats/作弊码行为crates/cheatcodes、crates/cheatcodes/src/evmdefault/fork/状态分叉crates/anvil/core、crates/evm/evmdefault/linking/库链接crates/linkingdefault/repros/历史缺陷回归视 issue 而定多为 crates/forge 与 crates/evmdefault/inline/内联配置解析crates/forge/src/runner.rsparis/、multi-version/编译器 profile 选择crates/config/src/compilation.rscheats/目录还充当anvil与forge的共享验收集例如Broadcast.t.sol、BroadcastRawTransaction.t.sol校验交易广播路径StateDiff*系列校验状态差异导出这些都是 crates/anvil 状态管理能力的行为契约。六、小结从测试套件读懂 Foundrytestdata/README.md用六行文字勾勒了 Foundry 测试套件的全貌而它背后的 testdata 目录则承载了数百个真实用例从core/的测试框架语义、cheats/的上百个作弊码验收、fork/的多链分叉到repros/的 issue 回归、linking/的链接边界与vyper/的跨语言支持。配合 testdata/foundry.toml 的 profile、编译限制与 RPC 配置这套套件既是一份Foundry 功能清单也是贡献者新增功能时必须同步维护的行为契约——理解它就等于拿到了阅读 Foundry 源码与参与其开发的最佳入口。【免费下载链接】foundryFoundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.项目地址: https://gitcode.com/GitHub_Trending/fo/foundry创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表