Testing
β
Unit
π Integration
π Fuzz
π Coverage
π Related Pages
π»OverviewSecurityDeploymentSmart ContractsLast updated
Last updated
contracts/
βββ src/
β βββ tokens/
β βββ nfts/
β βββ governance/
β βββ financial/
βββ test/
β βββ unit/
β βββ integration/
β βββ fuzz/
βββ script/
βββ foundry.toml# foundry.toml
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']
solc = '0.8.33'
[profile.ci]
fuzz = { runs = 10000 }
[rpc_endpoints]
base = "${BASE_RPC_URL}"// test/unit/BLTBYToken.t.sol
pragma solidity ^0.8.33;
import "forge-std/Test.sol";
import "src/tokens/BLTBYToken.sol";
contract BLTBYTokenTest is Test {
BLTBYToken public token;
address public admin = address(1);
address public user = address(2);
function setUp() public {
vm.startPrank(admin);
token = new BLTBYToken();
vm.stopPrank();
}
function test_InitialSupply() public {
assertEq(token.totalSupply(), 0);
}
function test_MintToUser() public {
vm.prank(admin);
token.mint(user, 1000e18);
assertEq(token.balanceOf(user), 1000e18);
}
}// Test reverts
function test_RevertWhen_NotAdmin() public {
vm.prank(user);
vm.expectRevert("Not authorized");
token.mint(user, 1000e18);
}
// Test events
function test_EmitOnMint() public {
vm.expectEmit(true, true, false, true);
emit Transfer(address(0), user, 1000e18);
vm.prank(admin);
token.mint(user, 1000e18);
}# Run all tests
forge test
# Run specific test
forge test --match-test test_MintToUser
# Run with verbosity
forge test -vvvcontract GovernanceIntegrationTest is Test {
Governance public gov;
Treasury public treasury;
MembershipNFT public membership;
EQTBLTToken public eqtblt;
function setUp() public {
// Deploy all contracts
eqtblt = new EQTBLTToken();
membership = new MembershipNFT();
treasury = new Treasury();
gov = new Governance(
address(treasury),
address(membership),
address(eqtblt)
);
// Wire up permissions
treasury.grantRole(GOVERNANCE_ROLE, address(gov));
}
function test_ProposalExecution() public {
// Create proposal
uint256 proposalId = _createProposal();
// Vote
_voteOnProposal(proposalId);
// Execute
vm.warp(block.timestamp + 7 days);
gov.execute(proposalId);
// Verify
assertTrue(treasury.proposalExecuted(proposalId));
}
}contract ForkTest is Test {
function setUp() public {
// Fork Base mainnet
vm.createSelectFork(vm.envString("BASE_RPC_URL"));
}
function test_InteractWithDeployed() public {
IERC20 usdc = IERC20(BASE_USDC);
// Test against real state
}
}# Run fork tests
forge test --fork-url $BASE_RPC_URLfunction testFuzz_MintAmount(uint256 amount) public {
// Bound to reasonable range
amount = bound(amount, 1, 100_000_000e18);
vm.prank(admin);
token.mint(user, amount);
assertEq(token.balanceOf(user), amount);
}contract TreasuryInvariantTest is Test {
Treasury treasury;
function setUp() public {
treasury = new Treasury();
// Setup initial state
}
/// @dev Treasury balance should never go negative
function invariant_PositiveBalance() public {
assertTrue(treasury.totalBalance() >= 0);
}
/// @dev Floor protection should hold
function invariant_AboveFloor() public {
assertTrue(
treasury.totalBalance() >= treasury.floor()
);
}
}[fuzz]
runs = 1000
max_test_rejects = 65536
[invariant]
runs = 256
depth = 15# Run fuzz tests
forge test --match-test testFuzz
# Run invariant tests
forge test --match-test invariant
# Increase runs
forge test --fuzz-runs 10000# Generate coverage report
forge coverage
# With LCOV format
forge coverage --report lcov
# Generate HTML report
genhtml lcov.info -o coverage# .github/workflows/test.yml
- name: Run tests
run: forge test -vvv
- name: Check coverage
run: |
forge coverage --report lcov
# Fail if below threshold
lcov --summary lcov.info | grep -q "90%"# Generate gas report
forge test --gas-report# Create snapshot
forge snapshot
# Compare to snapshot
forge snapshot --diff// Gas-efficient loop
for (uint256 i; i < length;) {
// operations
unchecked { ++i; }
}contract GasTest is Test {
function test_GasMint() public {
uint256 gasBefore = gasleft();
token.mint(user, 1000e18);
uint256 gasUsed = gasBefore - gasleft();
emit log_named_uint("Gas used", gasUsed);
assertLt(gasUsed, 100000);
}
}