description |
---|
Learn how to set up Foundry and use the Forge command-line tool to run your smart contract tests written in Solidity. |
- Configure Foundry and Forge with a Hedera Project
- Write unit tests in Solidity
- Run your tests using Foundry
forge
command - Create a Forge Gas Report
Before you begin, you should be familiar with the following:
Also, you should have the following set up on your computer ⬇
- git installed
- Minimum version: 2.37
- Recommended: Install Git (Github)
- A code editor or IDE
- Recommended: VS Code. Install VS Code (Visual Studio)
- NodeJs + npm installed
- Minimum version of NodeJs: 18
- Minimum version of npm: 9.5
- Recommended for Linux & Mac: nvm
- Recommended for Windows: nvm-windows
Check your prerequisites set up ⬇
Open your terminal, and enter the following commands.
git --version
code --version
node --version
npm --version
Ensure these versions meet or exceed the minimum requirements:
git --version
git version 2.39.2 (Apple Git-143)
code --version
1.81.1
6c3e3dba23e8fadc360aed75ce363ba185c49794
arm64
node --version
v20.6.1
npm --version
9.8.1
To follow along, start with the main
branch, which is the default branch of this repository. This gives you the initial state from which you can follow along with the steps as described in the tutorial.
git clone [email protected]:hedera-dev/setup-foundry-and-write-basic-unit-test.git
Forge manages dependencies by using git submodules. Run the steps below to add and install the git submodules necessary to use Forge.
Next, add the Forge Standard Library to your project:
cd setup-foundry-and-write-basic-unit-test
git submodule add https://github.com/foundry-rs/forge-std lib/forge-std
This command will add the forge standard library to our project by creating a folder named lib
. The forge standard library is the preferred testing library when working with Foundry.
Foundryup represents Foundry's tool management approach. Executing this command will install forge
and other essential Foundry CLI tools.
curl -L https://foundry.paradigm.xyz | bash
You should see output similar to the following:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 1942 100 1942 0 0 3336 0 --:--:-- --:--:-- --:--:-- 0
Installing foundryup...
######################################################################## 100.0%
Detected your preferred shell is zsh and added foundryup to PATH. Run 'source /Users/abi/.zshenv' or start a new terminal session to use foundryup.
Then, simply run 'foundryup' to install Foundry.
{% hint style="warning" %}
You may need to add foundry to PATH and open a new terminal to make the foundryup
command available. Then run foundryup
to install Foundry.
{% endhint %}
Once you've installed foundry you should get a similar output
xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx
╔═╗ ╔═╗ ╦ ╦ ╔╗╔ ╔╦╗ ╦═╗ ╦ ╦ Portable and modular toolkit
╠╣ ║ ║ ║ ║ ║║║ ║║ ╠╦╝ ╚╦╝ for Ethereum Application Development
╚ ╚═╝ ╚═╝ ╝╚╝ ═╩╝ ╩╚═ ╩ written in Rust.
.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx
Repo : https://github.com/foundry-rs/
Book : https://book.getfoundry.sh/
Chat : https://t.me/foundry_rs/
Support : https://t.me/foundry_support/
Contribute : https://github.com/orgs/foundry-rs/projects/2/
.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx
foundryup: installing foundry (version nightly, tag nightly)
foundryup: downloading latest forge, cast, anvil, and chisel
######################################################################### 100.0%
foundryup: downloading manpages
######################################################################### 100.0%
foundryup: installed - forge 0.2.0 (5ea2c5e 2024-01-22T00:24:09.322705000Z)
foundryup: installed - cast 0.2.0 (5ea2c5e 2024-01-22T00:24:09.341247000Z)
foundryup: installed - anvil 0.2.0 (5ea2c5e 2024-01-22T00:24:09.359481000Z)
foundryup: installed - chisel 0.2.0 (5ea2c5e 2024-01-22T00:24:09.377345000Z)
foundryup: done!
forge install
In order to make the import of the forge standard library easier to write, we will remap the dependency.
Open the project setup-foundry-and-write-basic-unit-test
, in a code editor.
Create a new text file under the root directory named remappings.txt
Paste in the following line of code
forge-std/=lib/forge-std/src/
When we want to import from forge-std
we will write: import "forge-std/Contract.sol"
A test file named TodoList.t.sol
has been provided to you under the test
folder.
On line 7, we see our TodoListTest
contract inherits Forge Standard Library's Test contract, which provides us access to the necessary functionality to test our smart contracts.
TodoList Test Contract
Create an instance of the contract TodoList.sol
in TodoList.t.sol
order to be able to test it.
TodoList public todoList;
{% hint style="warning" %} Look for a comment in the code to locate the specific lines of code that you will need to edit. For example, in this step, look for this: // Step (1) in the accompanying tutorial. You will need to delete the inline comment that looks like this: /* ... */. Replace it with the correct code. {% endhint %}
The setup()
function is invoked before each test case is run and is optional. Have the TodoList.t.sol
test contract deploy a new TodoList contract by adding the following code in the setUp()
function.
todoList = new TodoList();
Assert that the numberOfTodosAfter
executing createTodo()
is equal to the numberOftodosBefore
+ 1.
assertEq(numberOfTodosAfter, (numberOfTodosBefore + 1), "create todo test");
Foundry expects the test
keyword as a prefix to distinguish a test. Therefore, all tests you want to run must be prefixed with the test
keyword.
Foundry expects the test
keyword as a prefix to distinguiash a test. Therefore, all tests that you want to run must be prefixed with the test
keyword.
In the terminal, ensure you are in the root project directory and build the project.
forge build
You should see output similar to the following:
[⠒] Compiling...
[⠔] Compiling 22 files with 0.8.23
[⠑] Solc 0.8.23 finished in 3.44s
Compiler run successful!
After a successful build, run your test.
forge test
You should see output similar to the following:
[⠢] Compiling...
No files changed, compilation skipped
Running 1 test for test/TodoList.t.sol:TodoListTest
[PASS] test_createTodo_returnsNumberOfTodosIncrementedByOne() (gas: 76346)
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.12ms
Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
By default forge test
only displays a minimal summary of a test, whether it failed or passed. You can display more detailed information by using the -v
flag and increasing the verbosity.
In the terminal, re-run your test but include a verbosity level 4. This will display stack traces for all tests, including the setup.
forge test -vvvv
Level 4 verbosity output
Level 4 verbosity output
You should see output similar to the following:
[⠢] Compiling...
No files changed, compilation skipped
Running 1 test for test/TodoList.t.sol:TodoListTest
[PASS] test_createTodo_returnsNumberOfTodosIncrementedByOne() (gas: 76346)
Traces:
[76346] TodoListTest::test_createTodo_returnsNumberOfTodosIncrementedByOne()
├─ [2325] TodoList::getNumberOfTodos() [staticcall]
│ └─ ← 0
├─ [68126] TodoList::createTodo("A new todo for you!")
│ └─ ← 1
└─ ← ()
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 580.08µs
Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
Forge has functionality built in to give you gas reports of your contracts. You can specify which contract should generate a gas report in the foundry.toml
file.
The foundry.toml
file is a configuration file that is used to configure forge.
Create a new file in the root directory named foundry.toml
. Paste the following contents.
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']
# Step 4 - Configure foundry to produce a gas report for `TodoList.sol`
#/* ... */
[rpc_endpoints]
h_testnet = "https://testnet.hashio.io/api"
h_mainnet = "https://mainnet.hashio.io/api"
# See more config options https://github.com/foundry-rs/foundry/tree/master/config
Replace the comment #/* ... */
with the line below:
gas_reports = ["TodoList"]
In the terminal, generate a gas report.
forge test --gas-report
You should see output similar to the following:
Test Contract Gas Report
Your output will show you an estimated gas average, median, and max for each contract function used in a test and total deployment cost and size.
Congratulations, you have completed how to setup Foundry and write a basic unit test.
You have learned how to:
- Configure Foundry and forge with a hedera project
- Write unit tests in Solidity
- Run your tests using Foundry
forge
command - Create a forge gas report
Writer: Abi Castro, DevRel Engineer | https://twitter.com/ridley___ |
Editor: Brendan, DevRel Engineer | https://blog.bguiz.com |