Skip to content

jmakwana0x1/Advanced-Foundry-Testing-Guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Advanced Foundry Testing Guide πŸ”¨

Medium License: MIT

A comprehensive guide to advanced testing patterns in Foundry for Ethereum smart contract development. This repository contains all the code examples and patterns discussed in my Medium blog series.

πŸ“ Blog Post

I've written an in-depth article about advanced Foundry testing patterns. Read it on Medium:

Advanced Foundry Testing Patterns: A Complete Guide

This repository serves as the companion code for the blog post, providing working examples of all the patterns and techniques discussed.

🎯 What's Inside

This guide covers advanced testing patterns that go beyond basic unit tests:

Core Testing Patterns

  • βœ… State tree testing
  • βœ… Time-based testing patterns
  • βœ… Access control testing
  • βœ… Event testing with vm.expectEmit
  • βœ… Snapshot and rollback patterns

Advanced Techniques

  • πŸ” Fuzz testing with bounds and assumptions
  • πŸ”„ Invariant testing with handlers
  • 🍴 Fork testing with mainnet state
  • πŸ” Security pattern testing (reentrancy, access control)
  • πŸ“Š Gas optimization testing
  • πŸ”„ Differential testing
  • 🎭 Mock and stub patterns

Real-World Scenarios

  • πŸ’Έ DeFi protocol integration testing
  • πŸŒ‰ Cross-chain bridge testing
  • ⬆️ Proxy and upgradeability testing
  • 🚨 Attack vector testing
  • πŸ’° Multi-user stateful fuzzing

πŸ“š Documentation Files

Main Guides

Code Examples

All examples are fully functional and can be run with Foundry.

πŸš€ Getting Started

Prerequisites

Make sure you have Foundry installed:

curl -L https://foundry.paradigm.xyz | bash
foundryup

Installation

  1. Clone the repository:
git clone https://github.com/jmakwana0x1/foundry-advanced-testing.git
cd foundry-advanced-testing
  1. Install dependencies:
forge install
  1. Run the tests:
forge test

Running Specific Examples

# Run all tests
forge test

# Run tests with gas reporting
forge test --gas-report

# Run specific test file
forge test --match-path test/ReentrancyTest.t.sol

# Run with verbosity for detailed output
forge test -vvvv

# Run fuzz tests only
forge test --match-test testFuzz

# Run invariant tests
forge test --match-test invariant

# Generate coverage report
forge coverage

# Create gas snapshot
forge snapshot

πŸ“– Guide Structure

1. Basic Testing Patterns

Learn the fundamentals of writing effective Foundry tests:

  • Setting up test environments
  • Using cheat codes (vm.prank, vm.warp, vm.roll)
  • Assertions and expectations
  • Test organization

2. Fuzz Testing

Master property-based testing:

  • Bounded fuzzing with bound()
  • Using assumptions with vm.assume()
  • Testing invariants across random inputs
  • Structured fuzzing strategies

3. Invariant Testing

Build robust invariant test suites:

  • Handler-based testing
  • Ghost variables for tracking
  • Multi-actor scenarios
  • Stateful fuzzing patterns

4. Fork Testing

Test against real deployed contracts:

  • Creating and managing forks
  • Impersonating accounts
  • Testing with live data
  • Multi-chain testing

5. Security Testing

Identify vulnerabilities:

  • Reentrancy attack patterns
  • Access control bypass testing
  • Flash loan manipulation
  • Integer overflow/underflow
  • Front-running scenarios

6. Gas Optimization

Optimize your contracts:

  • Gas profiling techniques
  • Comparative gas analysis
  • Snapshot-based regression testing
  • Identifying optimization opportunities

πŸ”§ Project Structure

foundry-advanced-testing/
β”œβ”€β”€ README.md
β”œβ”€β”€ foundry-advanced-guide.md
β”œβ”€β”€ foundry-real-world-examples.md
β”œβ”€β”€ foundry.toml
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ examples/
β”‚   β”‚   β”œβ”€β”€ Token.sol
β”‚   β”‚   β”œβ”€β”€ Vault.sol
β”‚   β”‚   β”œβ”€β”€ LendingPool.sol
β”‚   β”‚   β”œβ”€β”€ AMM.sol
β”‚   β”‚   └── ...
β”‚   └── security/
β”‚       β”œβ”€β”€ VulnerableBank.sol
β”‚       β”œβ”€β”€ ProtectedBank.sol
β”‚       └── ...
└── test/
    β”œβ”€β”€ unit/
    β”‚   β”œβ”€β”€ Token.t.sol
    β”‚   └── Vault.t.sol
    β”œβ”€β”€ integration/
    β”‚   β”œβ”€β”€ DeFiIntegration.t.sol
    β”‚   └── MultiContract.t.sol
    β”œβ”€β”€ invariant/
    β”‚   β”œβ”€β”€ BankInvariant.t.sol
    β”‚   └── AMMInvariant.t.sol
    β”œβ”€β”€ fork/
    β”‚   └── MainnetFork.t.sol
    └── security/
        β”œβ”€β”€ ReentrancyTest.t.sol
        └── AccessControlTest.t.sol

πŸ’‘ Key Concepts

Cheat Codes Reference

Cheat Code Purpose Example
vm.prank(address) Set msg.sender for next call vm.prank(alice); token.transfer(bob, 100);
vm.startPrank(address) Set msg.sender for all calls vm.startPrank(alice);
vm.warp(timestamp) Set block.timestamp vm.warp(block.timestamp + 1 days);
vm.roll(number) Set block.number vm.roll(block.number + 100);
vm.deal(address, amount) Set ETH balance vm.deal(alice, 100 ether);
vm.expectRevert() Expect next call to revert vm.expectRevert("Error");
vm.expectEmit() Expect event emission vm.expectEmit(true, true, false, true);

Test Naming Conventions

test_Description()              // Basic test
testFail_Description()          // Expected to fail (deprecated, use expectRevert)
testRevert_Description()        // Expect revert with reason
testFuzz_Description(args)      // Fuzz test
invariant_Description()         // Invariant test

πŸŽ“ Learning Path

  1. Start with the basics - Read foundry-advanced-guide.md sections 1-3
  2. Try simple examples - Run the unit tests
  3. Explore fuzzing - Understand property-based testing
  4. Master invariants - Build handler-based test suites
  5. Real-world scenarios - Study foundry-real-world-examples.md
  6. Security focus - Learn attack vectors and defenses

πŸ› οΈ Advanced Configuration

foundry.toml

[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.24"

[profile.default.fuzz]
runs = 256
max_test_rejects = 65536

[profile.default.invariant]
runs = 256
depth = 15
fail_on_revert = false

[profile.ci]
fuzz = { runs = 5000 }
invariant = { runs = 1000 }

πŸ“Š Example Test Output

$ forge test --gas-report

Running 47 tests for test/Token.t.sol:TokenTest
[PASS] test_Mint() (gas: 45123)
[PASS] test_Transfer() (gas: 67234)
[PASS] testFuzz_TransferAmounts(uint256) (runs: 256, ΞΌ: 65432, ~: 65234)
[PASS] invariant_totalSupplyEqualsBalances() (runs: 256, calls: 3840, reverts: 156)

Test result: ok. 47 passed; 0 failed; finished in 2.34s

| Contract | Function      | Gas     |
|----------|---------------|---------|
| Token    | mint          | 45123   |
| Token    | transfer      | 67234   |
| Token    | approve       | 44567   |

🀝 Contributing

While this is primarily an educational repository for my blog post, I welcome:

  • πŸ› Bug reports
  • πŸ’‘ Suggestions for additional patterns
  • πŸ“ Improvements to documentation
  • ✨ Additional examples

Please open an issue or submit a pull request!

πŸ“¬ Contact & Follow

If you found this guide helpful, please:

  • ⭐ Star this repository
  • πŸ‘ Clap for the Medium article
  • πŸ”„ Share with fellow developers

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • The Foundry team for creating an amazing development framework
  • The Ethereum development community
  • Everyone who contributed feedback and suggestions

πŸ“š Additional Resources


Happy Testing! πŸŽ‰


Made with ❀️ for the Ethereum developer community

Last updated: February 2026

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors