Used to auto-generate unit tests for smart contracts using the Forge framework.
Project description
Olympix Test Generator
Olympix Test Generator is a Python-based utility tool to streamline the process of generating unit tests for Solidity smart contracts. These unit tests are tailored to be compatible with Foundry, a specialized tool for writing unit tests in Solidity.
Prerequisites
- Python 3.7 or later
- Solidity 0.8.0 or later
Installation
Install the Olympix Test Generator through pip:
pip install olympix-test-generator
Configuration
Prior to running the script, you'll need to set the OLYMPIX_API_KEY environment variable in your system.
For Unix or Linux:
export OLYMPIX_API_KEY=your-api-key
For Windows:
setx OLYMPIX_API_KEY "your-api-key"
Usage
Olympix Test Generator offers a command-line interface for creating tests.
Initiate the test generation process with:
olympix generate
Upon executing the command, the tool will guide you through the steps required to generate the test.
A test contract will be created either in the same directory as the chosen smart contract, or in an adjacent test folder, should one exist. Existing files will remain unaffected. The generated tests are also displayed on the console.
For optimal results, generate tests for one function at a time.
Sure, here's an improved version of the section:
Example - Contract and Generated Tests
In this section, we provide two examples of how the Olympix Test Generator works with different contracts: a smaller contract, Counter.sol, and a larger contract, MyToken.sol.
Example 1: Counter.sol
The Counter.sol contract is a simple contract that counts a number. The associated Counter.t.sol test contract is generated using our tool. All tests pass with 100% code coverage.
Counter.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
contract Counter {
uint256 public number;
function setNumber(uint256 newNumber) public {
number = newNumber;
}
function increment() public {
number++;
}
}
Generated Test: Counter.t.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import {Counter} from "../src/Counter.sol";
import "forge-std/Test.sol";
contract CounterTest is Test {
Counter counter;
function setUp() public {
counter = new Counter();
}
function test_initialNumber() public {
assertEq(counter.number(), 0);
}
function test_setNumber() public {
counter.setNumber(5);
assertEq(counter.number(), 5);
}
function test_increment() public {
counter.increment();
assertEq(counter.number(), 1);
}
}
Example 2: MyToken.sol
MyToken.sol is a more complex contract that implements a basic ERC20 token. Due to its complexity, we generate tests specifically for the approve function, resulting in the MyTokenApprove.t.sol test contract. We recommend this approach—generating tests for individual functions—for larger, more complex contracts.
MyToken.sol
// SPDX-License-Identifier: MIT
//pragma solidity >=0.4.22 <0.9.0;
pragma solidity 0.8.2;
contract MyToken {
// Mapping from account addresses to current balance.
mapping(address => uint256) private _balances;
// Mapping from account addresses to a mapping of spender addresses to an amount of allowance.
mapping(address => mapping(address => uint256)) private _allowances;
// Name of the token
string private _name;
// Symbol of the token
string private _symbol;
// Total of the token supply
uint256 private _totalSupply;
constructor(string memory name_, string memory symbol_, uint256 totalSupply_) {
_name = name_;
_symbol = symbol_;
_totalSupply = totalSupply_;
_balances[msg.sender] = totalSupply_;
}
function name() public view returns(string memory) {
return _name;
}
function symbol() public view returns(string memory) {
return _symbol;
}
function totalSupply() public view returns(uint256) {
return _totalSupply;
}
function balanceOf(address account) public view returns(uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public returns(bool) {
require(recipient != address(0), "ERC20: transfer to the zero address");
require(_balances[msg.sender] >= amount, "ERC20: transfer amount exceeds balance");
_balances[msg.sender] -= amount;
_balances[recipient] += amount;
emit Transfer(msg.sender, recipient, amount);
return true;
}
function approve(address spender, uint256 amount) public returns(bool) {
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function allowance(address owner, address spender) public view returns(uint256) {
return _allowances[owner][spender];
}
function transferFrom(address sender, address recipient, uint256 amount) public returns(bool) {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
require(_balances[sender] >= amount, "ERC20: transfer amount exceeds balance");
require(_allowances[sender][msg.sender] >= amount, "ERC20: transfer amount exceeds allowance");
_balances[sender] -= amount;
_balances[recipient] += amount;
_allowances[sender][msg.sender] -= amount;
emit Transfer(sender, recipient, amount);
return true;
}
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
Generated Test: MyTokenApprove.t.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import {MyToken} from "../src/MyToken.sol";
import "forge-std/Test.sol";
contract MyTokenTest is Test {
MyToken myToken;
address spender;
function setUp() public {
myToken = new MyToken("My Token", "MTK", 1000000);
spender = address(0x123);
}
function test_approve() public {
uint256 amount = 500;
bool success = myToken.approve(spender, amount);
assert(success);
uint256 allowance = myToken.allowance(address(this), spender);
assertEq(allowance, amount, "Allowance does not match approved amount");
}
}
In both cases, the Olympix Test Generator produces compact and efficient test contracts, which can help you ensure the reliability and security of your Solidity contracts.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file olympix-test-generator-1.2.2.tar.gz.
File metadata
- Download URL: olympix-test-generator-1.2.2.tar.gz
- Upload date:
- Size: 6.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1d8a09886b3dff730c8e8d605881ab2b9a2226e8393f5536a4cf34963c667a5
|
|
| MD5 |
facb3deba84a6a025492ab3e747d52f9
|
|
| BLAKE2b-256 |
620d8667b21b874522052f10ad3a7ea85706a21144c4803129aaf129bd81b53d
|
File details
Details for the file olympix_test_generator-1.2.2-py3-none-any.whl.
File metadata
- Download URL: olympix_test_generator-1.2.2-py3-none-any.whl
- Upload date:
- Size: 6.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
10b0ffc13be96ae4888349f9ae60eac7af0d1c3f13a11f9ff886b755e77ff8de
|
|
| MD5 |
6303d7732514cfe210de184ab593c88c
|
|
| BLAKE2b-256 |
193e606125b715a5c22b5137b35b2ca9cf86ade67cbbbda01bbb5668f38f0642
|