Package: olympix-test-generator
Olympix Test GeneratorOlympix 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 withFoundry, a specialized tool for writing unit tests in Solidity.PrerequisitesPython 3.7 or laterSolidity 0.8.0 or laterInstallationInstall the Olympix Test Generator through pip:pipinstallolympix-test-generatorConfigurationPrior to running the script, you'll need to set theOLYMPIX_API_KEYenvironment variable in your system.For Unix or Linux:exportOLYMPIX_API_KEY=your-api-keyFor Windows:setx OLYMPIX_API_KEY "your-api-key"UsageOlympix Test Generator offers a command-line interface for creating tests.Initiate the test generation process with:olympixgenerateUpon 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 TestsIn 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.solTheCounter.solcontract is a simple contract that counts a number. The associatedCounter.t.soltest contract is generated using our tool. All tests pass with 100% code coverage.Counter.sol// SPDX-License-Identifier: UNLICENSEDpragma solidity^0.8.13;contractCounter{uint256publicnumber;functionsetNumber(uint256newNumber)public{number=newNumber;}functionincrement()public{number++;}}Generated Test: Counter.t.sol//SPDX-License-Identifier: UNLICENSEDpragma solidity^0.8.13;import{Counter}from"../src/Counter.sol";import"forge-std/Test.sol";contractCounterTestisTest{Countercounter;functionsetUp()public{counter=newCounter();}functiontest_initialNumber()public{assertEq(counter.number(),0);}functiontest_setNumber()public{counter.setNumber(5);assertEq(counter.number(),5);}functiontest_increment()public{counter.increment();assertEq(counter.number(),1);}}Example 2: MyToken.solMyToken.solis a more complex contract that implements a basic ERC20 token. Due to its complexity, we generate tests specifically for theapprovefunction, resulting in theMyTokenApprove.t.soltest 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 solidity0.8.2;contractMyToken{// 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 tokenstringprivate_name;// Symbol of the tokenstringprivate_symbol;// Total of the token supplyuint256private_totalSupply;constructor(stringmemoryname_,stringmemorysymbol_,uint256totalSupply_){_name=name_;_symbol=symbol_;_totalSupply=totalSupply_;_balances[msg.sender]=totalSupply_;}functionname()publicviewreturns(stringmemory){return_name;}functionsymbol()publicviewreturns(stringmemory){return_symbol;}functiontotalSupply()publicviewreturns(uint256){return_totalSupply;}functionbalanceOf(addressaccount)publicviewreturns(uint256){return_balances[account];}functiontransfer(addressrecipient,uint256amount)publicreturns(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;emitTransfer(msg.sender,recipient,amount);returntrue;}functionapprove(addressspender,uint256amount)publicreturns(bool){require(spender!=address(0),"ERC20: approve to the zero address");_allowances[msg.sender][spender]=amount;emitApproval(msg.sender,spender,amount);returntrue;}functionallowance(addressowner,addressspender)publicviewreturns(uint256){return_allowances[owner][spender];}functiontransferFrom(addresssender,addressrecipient,uint256amount)publicreturns(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;emitTransfer(sender,recipient,amount);returntrue;}eventTransfer(addressindexedfrom,addressindexedto,uint256value);eventApproval(addressindexedowner,addressindexedspender,uint256value);}Generated Test: MyTokenApprove.t.sol// SPDX-License-Identifier: UNLICENSEDpragma solidity^0.8.0;import{MyToken}from"../src/MyToken.sol";import"forge-std/Test.sol";contractMyTokenTestisTest{MyTokenmyToken;addressspender;functionsetUp()public{myToken=newMyToken("My Token","MTK",1000000);spender=address(0x123);}functiontest_approve()public{uint256amount=500;boolsuccess=myToken.approve(spender,amount);assert(success);uint256allowance=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.