HackQuest_Forge_Std

Forge
即forge标准库。为foundry框架提供一套丰富的辅助合约集合。
forge-std
forge-std旨在简化和加速智能合约的测试编写过程,提升用户体验。
Usage
1 | import "forge-std/Test.sol"; |
Function
- 访问Hevm:通过vm实例,可以直接模拟区块链的状态和行为。
- 断言与日志记录。
- 标准库功能。
Import Example
1 | import "forge-std/Vm.sol"; |
组成
- std logs: 基于DSTest库的日志事件功能进行了扩展。
- std assertions:对DSTest断言函数进行了扩展
- std cheats: Std Cheats 为 Forge cheatcodes 提供了安全的封装,改善了开发体验。通过在测试合约中调用它们,可以轻松实现身份伪装、账户余额设置等操作。
- std errors:Std Errors 提供了对常见 Solidity 错误和回退的封装,与 expectRevert cheatcode 结合使用时,无需记住 Solidity 内部的 panic 代码。
- std storage: Std Storage 简化了合约存储的操作,使得查找和修改特定变量的存储位置变得简单直接。
- std math: Std Math 库提供了 Solidity 中未提供的有用数学函数,为开发者提供了更多的数学运算支持。
flowchart LR r[forge-std] n1[std logs] n2[std assertions] n3[std cheats] n4[std errors] n5[std storage] n6[std math] r --> n1 r --> n2 r --> n3 r --> n4 r --> n5 r --> n6
cheatcode介绍
cheatcode:作弊码。
可以操作区块链的状态,测试特定的还原操作和事件。
作弊码允许开发者测试中执行一些非标准操作。
比如:更改区块号,修改调用者身份,修改fork(切换网络)等。
在forge标准库的Test合约中,可以通过vm
实现访问作弊码。
Usage
- vm.prank,身份切换,暂时切换调用者身份;
1 | pragma solidity 0.8.10; |
- vm.createFork(RPC_URL):创建一个Fork实例;
- vm.selectFork(Fork_实例):切换到指定Fork。
- vm.ffi(ARGS):运行外部命令,返回执行结果。
(下面的内容讲的有些乱,挖坑)
vm.expectEmit
Foundry编写测试
Usage
编写测试类
- 导入Test.sol
- 编写测试类:
contract <ContractName> is Test
- 编写setUp:
function setUp() public {}
- 编写测试逻辑:这里指的是数个方法,以
test/testFail
开头
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22pragma solidity ^0.8.13;
//1. 导入Test.sol
import "forge-std/Test.sol";
//2. 编写测试类
contract ContractBTest is Test {
uint256 testNumber;//
//3. 数据初始化
function setUp() public {
testNumber = 42;
}
//4. 测试逻辑
function test_Subtract43() public {
vm.expectRevert(stdError.arithmeticError);
console2.log("testNumber = %d", testNumber);
testNumber -= 43;
}
}执行测试(参照:上一个日记)
1
forge test
测试逻辑编写
测试逻辑由数个
test方法
组成。对于
test方法
,必须以test / testFail
开头。对于forge的测试过程,会测试所有的
test方法
,最后输出通过的数量和不通过的数量。
对于test / testFail
使用test标记的方法,如果该方法在运行过程中没有报错,则表示通过;
testFail反之,如果报错了,则通过,否则为测试失败/不通过。
更精确的测试处理
1 | function test_MyRevertCase() public { |
vm.expectRevert(<Error>.selector);
表示接下来的操作必须发生指定错误才能通过测试。
OTHER
- 测试函数必须声明为external或public
- 使用setUp设定共享设置,减少重复代码。
自动多次随机数据测试Fuzz Testing
Fuzz Testing可以为测试方法提供随机参数,并进行多次测试。
Usage
- 方法名以
testFuzz
开头
1 | function testFuzz_Withdraw(uint256 amount) public {} |
- 限定参数范围:
设定参数类型
或使用vm.assume作弊码
1 | function testFuzz_Withdraw(uint96 amount) public {}// uint96限定测试范围 |
评论