
Chapter 0x5: Foundry Testing and Interacting Smart Contracts For Beginners Best Guide
Table of Contents
📌 What is the Foundry Testing Framework?
Foundry Testing and Interacting Smart Contracts : If you’re diving into Solidity smart contract development, you must be familiar with testing frameworks like Hardhat and Truffle. But have you heard of Foundry? Foundry is a blazing-fast, Rust-based development framework for Ethereum smart contracts. It provides a seamless way to write, test, and deploy smart contracts. In this article, we’ll go deep into writing unit tests using Foundry, handling assertions and errors, and interacting with smart contracts.
By the end of this tutorial, you’ll have a strong grasp of Foundry’s testing capabilities and will be able to write robust smart contract tests efficiently.
🚀 Why Choose Foundry Over Other Testing Frameworks?

Many developers ask, “Foundry vs Hardhat?” Let’s break it down:
- Speed: Foundry is significantly faster than Hardhat because it’s written in Rust.
- Built-in Testing: Foundry comes with its own testing framework, eliminating the need for external libraries like Mocha/Chai in Hardhat.
- Native Solidity Scripting: Foundry allows you to write tests in Solidity itself, making it easier to interact with contracts directly.
- Ease of Use: It simplifies contract deployment, interaction, and testing compared to Hardhat.
🛠 Getting Started with Foundry
Before we start writing tests, let’s set up Foundry on your system.
1️⃣ Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup
2️⃣ Initialize a Foundry Project
forge init MyFoundryProject
cd MyFoundryProject
Now, you have a Foundry project ready to go! 🎉
🧪 Writing Simple Unit Tests Using forge test
forge test

forge test
Foundry comes with a built-in testing framework called forge test
. Unlike JavaScript-based testing frameworks, Foundry tests are written in Solidity, making them more intuitive for Solidity developers.
✍ Writing a Simple Test
Let’s create a simple Counter.sol
contract and test it using Foundry.
Counter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract Counter {
uint256 public count;
function increment() public {
count += 1;
}
}
Now, let’s write a test file CounterTest.t.sol
to test this contract.
CounterTest.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import "forge-std/Test.sol";
import "../src/Counter.sol";
contract CounterTest is Test {
Counter counter;
function setUp() public {
counter = new Counter();
}
function testIncrement() public {
counter.increment();
assertEq(counter.count(), 1);
}
}
🛠 Running the Test
Now, run the test using:
forge test
You’ll see an output like this:
[PASS] CounterTest::testIncrement() (gas: 3000)
Congratulations! 🎉 You just wrote your first Foundry unit test!
🛠 Assertions and Error Handling in Foundry Tests

Foundry provides several assertion functions to validate expected behavior:
- assertEq(actual, expected) → Ensures values are equal
- assertTrue(condition) → Ensures a condition is true
- assertFalse(condition) → Ensures a condition is false
❌ Testing for Reverts
Foundry allows testing for errors using vm.expectRevert()
.
Example:
function testRevert() public {
vm.expectRevert("Error Message");
revert("Error Message");
}
This ensures the function throws the expected error.
🤝 Interacting with Smart Contracts in Foundry

Foundry allows seamless interaction with smart contracts in tests and scripts.
📜 Calling Functions
counter.increment();
uint256 newCount = counter.count();
assertEq(newCount, 1);
⛽ Simulating Transactions
Foundry enables sending transactions using vm.prank()
(for setting msg.sender
) and vm.startPrank()
.
Example:
function testWithDifferentSender() public {
address fakeUser = address(0x123);
vm.prank(fakeUser);
counter.increment();
}
This makes it appear as if fakeUser called increment()
.
📖 Intermediate Topics: Foundry Testing in Depth
Now that you’ve mastered the basics, let’s explore advanced Foundry testing techniques:
1️⃣ Writing More Complex Tests
Foundry supports testing multiple scenarios in one test file. For example, let’s test a more complex smart contract Bank.sol.
Bank.sol
contract Bank {
mapping(address => uint256) public balances;
function deposit() external payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint256 amount) external {
require(balances[msg.sender] >= amount, "Insufficient funds");
balances[msg.sender] -= amount;
payable(msg.sender).transfer(amount);
}
}
BankTest.t.sol
contract BankTest is Test {
Bank bank;
function setUp() public {
bank = new Bank();
}
function testDeposit() public {
vm.deal(address(this), 10 ether);
bank.deposit{value: 1 ether}();
assertEq(bank.balances(address(this)), 1 ether);
}
}
Run tests using:
forge test
This ensures our Bank contract works correctly! 🏦
Learn Smart Contract Development using in Solidity Programming Tutorial
📚 Resources to Learn More About Foundry
Here are some resources to deepen your Foundry knowledge:
🎯 Final Thoughts
Foundry is a game-changer for Solidity developers looking for a fast, efficient, and Solidity-native testing framework. Whether you’re a beginner or an expert, Foundry simplifies smart contract development, making it easier to write and test Solidity code.
💡 Key Takeaways
✅ Fast and efficient testing with forge test
✅ Solidity-native scripting and debugging
✅ Advanced testing features like vm.expectRevert()
✅ Seamless contract interactions with vm.prank()
With Foundry, you can write better tests, catch bugs early, and deploy smart contracts with confidence. 🚀
Have questions? Drop them in the comments below! Happy coding! 💻🔥