0Pricing
Web3 & DApp Development Fundamentals · 课时

forge 测试

Solidity 测试

forge 测试 是 CoddyKit 上的免费 Web3 & DApp Development Fundamentals 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Web3 & DApp Development Fundamentals 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Web3 & DApp Development Fundamentals 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

Tests Are Contracts

In Foundry a test file is a Solidity contract that inherits from Test in the forge-std library. Each public function whose name starts with test is run as an individual test case.

Test files live in test/ and conventionally use the .t.sol suffix.

import {Test} from "forge-std/Test.sol";

contract CounterTest is Test {
    function testInitialZero() public {
        // ...
    }
}

The setUp Function

The special setUp() function runs before every test, giving each test a fresh, isolated state. Deploy your contracts and seed any fixtures here.

Because state resets between tests, one test can never accidentally depend on another.

Counter counter;

function setUp() public {
    counter = new Counter();
}

Assertions

forge-std provides assertion helpers that fail the test with a clear message when they do not hold:

  • assertEq(a, b) — equality
  • assertTrue(cond) / assertFalse(cond)
  • assertGt, assertLt, assertGe, assertLe
function testIncrement() public {
    counter.increment();
    assertEq(counter.number(), 1);
}

Running Tests

Run the whole suite with forge test. Filter by name with --match-test or by contract with --match-contract. Increase verbosity with -v flags to see logs and traces.

$ forge test
$ forge test --match-test testIncrement -vvv

Expecting Reverts

Use vm.expectRevert immediately before a call that should fail. The test passes only if the next call reverts, optionally matching a specific error message or custom error.

function testOnlyOwner() public {
    vm.prank(address(0xBEEF));
    vm.expectRevert("not owner");
    counter.adminReset();
}

Impersonating Accounts

vm.prank(addr) sets msg.sender for the very next call. vm.startPrank(addr) applies it to all calls until vm.stopPrank(). This lets you test access control without deploying from many keys.

vm.startPrank(alice);
token.approve(spender, 100);
token.transfer(bob, 50);
vm.stopPrank();

Manipulating Balances and Time

Cheatcodes let you control the environment:

  • vm.deal(addr, amount) — set an account's ETH balance
  • vm.warp(timestamp) — set block.timestamp
  • vm.roll(blockNum) — set block.number

These make time-dependent and balance-dependent logic easy to test deterministically.

vm.deal(alice, 10 ether);
vm.warp(block.timestamp + 7 days);
vm.roll(block.number + 100);

Testing Events

vm.expectEmit declares which event fields to check, followed by the expected event, then the call that should emit it. The booleans select which topics and data to match.

vm.expectEmit(true, true, false, true);
emit Transfer(alice, bob, 100);
token.transfer(bob, 100);

Labels and Logs

vm.label(addr, name) gives addresses readable names in traces. console.log from forge-std prints debug output during tests when run with sufficient verbosity.

import {console} from "forge-std/console.sol";

vm.label(alice, "Alice");
console.log("balance:", token.balanceOf(alice));

Fork Testing

Foundry can fork a live network so your tests run against real deployed contracts and state. Set an RPC URL and use vm.createSelectFork to pin a block.

This is invaluable for testing integrations with protocols like Uniswap or Aave without redeploying them.

function setUp() public {
    vm.createSelectFork(vm.rpcUrl("mainnet"), 19000000);
}

Test Organization

Good practices for forge tests:

  • One behavior per test function
  • Descriptive names like testRevertWhenNotOwner
  • Shared setup in setUp()
  • Use prank for access control, warp for time logic
  • Add fork tests for external integrations

Quick Check

What is the purpose of the setUp() function in a Foundry test contract?

Recap

You learned forge testing:

  • Tests are Solidity contracts inheriting Test; functions start with test
  • setUp() gives fresh state per test
  • Assertions: assertEq, assertTrue, etc.
  • Cheatcodes: prank, deal, warp, expectRevert, expectEmit
  • Fork tests run against live network state

Next: fuzzing and invariant testing.

常见问题解答

「forge 测试」课时是免费的吗?

是的 — 「forge 测试」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Web3 & DApp Development Fundamentals 课程的其余内容,请升级到 CoddyKit PRO。 Web3 & DApp Development Fundamentals 课程共包含 4 节课。

「forge 测试」这节课中我会学到什么?

Solidity 测试 你通过在浏览器中直接运行的动手代码来练习 Web3 & DApp Development Fundamentals,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Web3 & DApp Development Fundamentals 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Web3 & DApp Development Fundamentals 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「forge 测试」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Web3 & DApp Development Fundamentals 课中编写并运行代码吗?

能。每节 Web3 & DApp Development Fundamentals 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Foundry 与 Hardhat 对比
  2. forge 测试
  3. 模糊测试与不变量
  4. cast 与 anvil
← 返回 Web3 & DApp Development Fundamentals