Swap tech notes, part 2: test coverage
Intro
This a second part of the seria of publications regarding work on the Swap project. It covers a test coverage of smart contracts.
Test coverage options
Over the Remix
Ethereum dev team provides its own IDE called Remix. Besides many
others things it allows to quickly deploy and run smart contracts.
It has convenient UI which provides a set of a smart contract
methods to interact with.
Remix functionality might be a good option to quickly verify a
correctness of just developed contract without many extra
dependencies.
However, it has several limitations where two major ones are lack
of logs and unclear error messages from the ledger.
Over an another smart contract
There is another interesting way to test smart contracts by
implementing another contract which will act as a robot which
invokes another contract interface methods and verify the result.
It is something I have met during my research. It still has
its place in the Ethereum test world. Despite on I picked up the
Hardhat, I use this approach too to verify things which are easier
to do on the contract layer.
Over the Hardhat
Hardhat is a development environment for Ethereum software.
. By being integrated into Visual Studio Code IDE it covers
all my current demands to the ethereum dev environment including
clear error messages from the ledger.
Hardhat runs code on its own locally deployed network which allows
to quickly deploy, execute and test contracts.
Deployment:
describe("Swap value suite", async function() { async function deploy() { const factory = await ethers.getContractFactory("SwapValue"); const contract = await factory.deploy(); const utilsFactory = await ethers.getContractFactory("Utils"); const contractUtils = await utilsFactory.deploy(); return { contract, contractUtils }; } // the rest test methods })
Test case:
it("On emit new tokens balance of user changes", async function() { const accounts = await ethers.getSigners(); const owner = accounts[0].address; const user1 = accounts[1].address; const { contract } = await loadFixture(deploy); await expect(await contract.balanceOf(owner)).to.be.equal(0); // {value: ethers.utils.parseEther("0.123") } const customMetadata = { _offer : "Software development for Android.", _availableSince: 0, _availabilityEnd: 0, _isConsumed: false, _lockedUntil: 1000 }; await contract.safeMint(owner, customMetadata, "https://gelassen.github.io/blog/"); await expect(await contract.balanceOf(owner)).to.be.equal(1); });
Over web3j on the mobile client
The test coverage on the mobile client (and server side) is done as a part of integration tests.
Testnets
After automating tests locally, it is still important to verify code
on the production chain. The Ethereum team & the community provides
special testnets for such purposes.
After the Merge event which has been happened in the middle of autumn
in 2022, only two testnets are left alive.
My experience with Sepolia testnet is negative, they had some issue
they promised to solve after 5th of october 2022, but even later
later I still experience with some issues.
After that the Goerly became is the only option left for tests, but
unexpectedly it became very slow.
Web3j has a time threshold of 10 minutes. Goerly testnet increases
time to mint a token - receive a receipt. It was near a minute on
10th of October, 4 hours 5 days later and 10.5 hours on 27th of
October
Not sure about exact cause of such changes in the testnet, but it
made further development quite slow and painful. After research I
decided to move to deploy own private network to continue
development. It was good because from business perspective I also
made a pivot to launch product on a private chain as it had been
shown in the previous publication of this seria.
Private chain
At the moment of writing Ethereum offers Mainnet and two test nets:
Sepolia and Goerli. A bunch of tools, e.g. hardhat, provides local
development testnet. However, deploying your own testnet on your
machine or VMs is out of scope in the official documentation.
There is a collection of available public testnets
https://chainlist.org/.
Ethereum official repository provides source code for chain and such
tool as puppeth
for a quick configuration of the private chain.
1. Create folders for nodes
2. Create accounts in nodes (we will need to remember address of the key and secret key by itself):
$geth --datadir ./node1/data account new
$geth --datadir ./node2/data account new
$geth --datadir ./node3/data account new
3. Generate genesis block (the main configuration file):
$puppeth
4. Export chain configuration:
$puppeth (reselect option 2. Manage existing genesis)
5. Initialize all nodes with chain config:
$geth --datadir ./node1/data init.json
$geth --datadir ./node2/data init.json
$geth --datadir ./node3/data init.json
6. Start nodes:
$geth --datadir ./node1/data --port 2001 (default authrpc.port 8551)
$geth --datadir ./node2/data --port 2002 --authrpc.port 8552
$geth --datadir ./node3/data --port 2003 --authrpc.port 8553
7. Link all nodes with a main one:
$geth attach ipc:node1/data/geth.ipc
$admin.nodeInfo.enode
(reply would be something similar to "enode://64dccd02d5d1166cfb4913f0d0c164dff2b9c61fd55182461010569e15319c7ff5cb4dc8b502e441c38c80ae1b42c2cc95c7e170ed973bb0353d766669c5447c@195.178.22.21:2001?discport=39805")
$geth attach ipc:node2/data/geth.ipc
$admin.addPeer(enode://64dccd02d5d1166cfb4913f0d0c164dff2b9c61fd55182461010569e15319c7ff5cb4dc8b502e441c38c80ae1b42c2cc95c7e170ed973bb0353d766669c5447c@127.0.0.1:2001")
Repeat for all nodes: each node should have reference in peers on all OTHERS nodes. Known issue: https://github.com/ethereum/go-ethereum/issues
8. To make node as a miner:
$geth attach ipc:node3/data/geth.ipc
$personal.unlockAccount()
$miner.setEtherbase()
$miner.start()
$miner.stop()
$eth.getBalance(eth.accounts[0])
What is next
This publication covers options to cover by tests ethereum smart
contracts, a recent state with testnets, a way to deploy private
network.
Automation tests strategy is to cover all general workflows,
important corner cases plus 'test per found bug'.
For more details you could check the source code. Part 1 of this
seria is available by link.
Next publications in this seria will cover backend & frontend and
their test coverage, project deployment automatization.