.claude/skills/forge-testing/SKILL.md
Write and run Solidity tests with Foundry. Use when writing unit tests, integration tests, or debugging test failures. Covers test structure, assertions, cheatcodes, and running tests with forge test.
npx skillsauth add cyotee/crane forge-testingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Write native Solidity tests using Foundry's testing framework.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Test, console} from "forge-std/Test.sol";
import {MyContract} from "../src/MyContract.sol";
contract MyContractTest is Test {
MyContract public target;
function setUp() public {
target = new MyContract();
}
function test_BasicFunction() public {
uint256 result = target.doSomething();
assertEq(result, 42);
}
function testFail_ShouldRevert() public {
target.functionThatReverts();
}
}
| Prefix | Behavior |
|--------|----------|
| test_ or test | Expected to pass |
| testFail_ or testFail | Expected to revert |
| testFuzz_ | Fuzz test with random inputs |
# Run all tests
forge test
# Run specific test contract
forge test --match-contract MyContractTest
# Run specific test function
forge test --match-test test_BasicFunction
# Run with verbosity (show logs)
forge test -vvv
# Watch mode
forge test --watch
| Flag | Output |
|------|--------|
| (none) | Summary only |
| -vv | Logs and assertion failures |
| -vvv | Stack traces for failures |
| -vvvv | Setup traces for failures |
| -vvvvv | All traces including setup |
See cheatcodes.md for the complete reference.
// Set caller for next call
vm.prank(address(0x123));
// Set caller for multiple calls
vm.startPrank(address(0x123));
// ... calls as 0x123
vm.stopPrank();
// Give ETH to address
vm.deal(address(0x123), 1 ether);
// Set block timestamp
vm.warp(block.timestamp + 1 days);
// Set block number
vm.roll(block.number + 100);
// Expect any revert
vm.expectRevert();
target.functionThatReverts();
// Expect specific error
vm.expectRevert("Insufficient balance");
target.withdraw(1000);
// Expect custom error
vm.expectRevert(InsufficientBalance.selector);
target.withdraw(1000);
// Expect event (check all indexed topics + data)
vm.expectEmit(true, true, true, true);
emit Transfer(from, to, amount);
target.transfer(to, amount);
See assertions.md for the complete reference.
// Equality
assertEq(a, b);
assertEq(a, b, "custom error message");
// Comparisons
assertGt(a, b); // a > b
assertGe(a, b); // a >= b
assertLt(a, b); // a < b
assertLe(a, b); // a <= b
// Approximate equality (for decimals)
assertApproxEqAbs(a, b, maxDelta);
assertApproxEqRel(a, b, maxPercentDelta);
// Boolean
assertTrue(condition);
assertFalse(condition);
import {console} from "forge-std/Test.sol";
console.log("Value:", someValue);
console.log("Address:", someAddress);
console.logBytes32(someHash);
See patterns.md for detailed examples.
address alice = makeAddr("alice");
address bob = makeAddr("bob");
vm.deal(alice, 10 ether);
vm.prank(alice);
target.deposit{value: 1 ether}();
function setUp() public {
vm.createSelectFork("mainnet");
}
function test_InteractWithMainnet() public {
IERC20 dai = IERC20(0x6B175474E89094C44Da98b954EesdfeCaE69310);
// Test against real mainnet state
}
// Write to specific storage slot
vm.store(address(target), bytes32(uint256(0)), bytes32(uint256(100)));
// Read from storage slot
bytes32 value = vm.load(address(target), bytes32(uint256(0)));
development
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
documentation
Write to contracts and send transactions. Use when executing state-changing contract functions.
development
HTTP and WebSocket transports for blockchain connectivity. Use when configuring network connections.
data-ai
Read contract data with type-safe ABI. Use when querying smart contract view/pure functions.