Solidity CRUD Tutorial, Part 2 — Testing Your Smart Contract with Truffle
Testing a Solidity smart contract using Truffle framework
In the last tutorial, we have created a smart contract which performs some basic CRUD (create, read, update, delete) operation, let’s test that smart contract using Truffle.
Truffle — Truffle is the most popular development and testing framework for developing ethereum smart contracts.
Installing Truffle
Prerequisites
Installation
- First, we need to install the Truffle package
sudo npm install -g truffle
- Verify that it has been downloaded successfully by running
truffle
Choose a directory and run
truffle init
It will create a directory structure and create few files.
Let’s go to these directories one by one an will understand what they are.
contracts/
: Directory for Solidity contractsmigrations/
: Directory for scriptable deployment filestest/
: Directory for test files for testing your application and contractstruffle.js
: Truffle configuration file
We will use truffle develop
to test our smart contract. Truffle gives us inbuilt development blockchain with ethereum accounts.
Let’s create a file with CrudApp.sol (Notice, same name as our contract name) under contracts directory and paste our smart contract code.
Let’s compile our smart contract using,
truffle compile
It may show some warnings but let’s ignore them for now. Open our development console using,
truffle develop
It will show an output something like below:
Truffle Develop started at http://127.0.0.1:9545/Accounts:
(0) 0x627306090abab3a6e1400e9345bc60c78a8bef57
(1) 0xf17f52151ebef6c7334fad080c5704d77216b732
(2) 0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef
(3) 0x821aea9a577a9b44299b9c15c88cf3087f3b5544
(4) 0x0d1d4e623d10f9fba5db95830f7d3839406c6af2
(5) 0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e
(6) 0x2191ef87e392377ec08e7c08eb105ef5448eced5
(7) 0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5
(8) 0x6330a553fc93768f612722bb8c2ec78ac90b3bbc
(9) 0x5aeda56215b167893e80b4fe645ba6d5bab767dePrivate Keys:
(0) c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3
(1) ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f
(2) 0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1
(3) c88b703fb08cbea894b6aeff5a544fb92e78a18e19814cd85da83b71f772aa6c
(4) 388c684f0ba1ef5017716adb5d21a053ea8e90277d0868337519f97bede61418
(5) 659cbb0e2411a44db63778987b1e22153c086a95eb6b18bdf89de078917abc63
(6) 82d052c865f5763aad42add438569276c00d3d88a2d062d36b2bae914d58b8c8
(7) aa3680d5d48a8283413f7a108367c7299ca73f553735860a87b08f39395618b7
(8) 0f62d96d6675f32685bbdb8ac13cda7c23436f63efbb9d07700d8669ff12b7c4
(9) 8d5366123cb560bb606379f90a0bfd4769eecc0557f1b362dcae9012b548b1e5Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat⚠️ Important ⚠️ : This mnemonic was created for you by Truffle. It is not secure.
Ensure you do not use it on production blockchains, or else you risk losing funds.truffle(develop)>
Your accounts and private keys will be different than mine.
Now we have accounts ready and our development blockchain spun up, we can test our smart contract.
Before that, let’s run few commands and test the balance of our accounts. Replace my account number with your account in the command below.
web3.eth.getBalance(“0x627306090abab3a6e1400e9345bc60c78a8bef57”)Result - BigNumber { s: 1, e: 20, c: [ 1000000 ] }
As you can see, above command gives result in BigNumber. You need to convert that into number format using .toNumber()
function.
web3.eth.getBalance("0x627306090abab3a6e1400e9345bc60c78a8bef57").toNumber()Result - 100000000000000000000
This shows balance in WEI (smallest ethereum unit / 1 ethereum = 1⁰¹⁸ wei). To convert this into the ether, you need to use web3.fromWei()
function.
web3.fromWei(web3.eth.getBalance(“0x627306090abab3a6e1400e9345bc60c78a8bef57”).toNumber())Result - '100' <<< Number of ethereum on the test account
Now, we need to deploy our smart contract.
You can use either deploy
command or migrate
command. You don’t need to prefix truffle
with commands on truffle CLI.
deploy
or
migrate
You can use reset flag ( — reset) while redeploying your contracts to get the initial state of the blockchain.
Test Cases-
Now let’s write some test cases to test our smart contract.
Create a file CrudApp.js (name should be same as smart contract file) under test
directory and copy below code.
const CrudApp = artifacts.require('./CrudApp.sol')
const assert = require('assert')let crudInstance;contract('CrudApp' , (accounts) => {
beforeEach(async () => {
crudInstance = await CrudApp.deployed()
})it('should insert new user' , async() => {
await crudInstance.insert("USA" , "Trump", 30000000);const country = await crudInstance.getCountry("USA");
assert.equal(country[0] , "USA");
assert.equal(country[1] , "Trump");
assert.equal(country[2].toNumber() , 30000000);await crudInstance.updateLeader("USA" , "Hillary");const country1 = await crudInstance.getCountry("USA");
assert.equal(country1[0] , "USA");
assert.equal(country1[1] , "Hillary");
assert.equal(country1[2].toNumber() , 30000000);await crudInstance.deleteCountry("USA");const total = await crudInstance.getTotalCountries();
assert.equal(total , 0);
})})
Let’s walk through our code and understand it.
We imported our contract and assert library, which created an instance of our contract after deploying it (CrudApp.deployed()
). Then we simply wrote three test case in which we are testing all four operations.
First, we are inserting a record and then updating and deleting it, respectively.
You can write test cases in Solidity too, but we choose Javascript, as Truffle makes it easy to test our contract.
You can also run few commands directly on Truffle console and also interact with our smart contract using Truffle CLI (Command Line Interface).
truffle(develop)> Above is what we calling Truffle CLI. Running commands on truffle.
Let’s get an instance of our smart contract using this command.
CrudApp.deployed().then(function(instance) { crud = instance;})
This will give us an instance (crud
) of our smart contract, let’s play with it. This instance is simple ABI (Application Binary Unterface) you can check it just printing crud
.
ABI is the interface between two program modules, one of which is often at the level of machine code. The interface is the de facto method for encoding/decoding data into/out of the machine code.
Let’s check the total number of countries by running this command.
crud.getTotalCountries().then(function(num){var str= num.toString(); console.log(str)});
Let insert a new country
crud.insert("USA","Trump",30000000);
The result should be something like this.
{ tx: '0x6502bd013b41f246e31f071690ffb1c8f41d21c4cddbad8bb99bf53d9ac6c982',
receipt:
{ transactionHash: '0x6502bd013b41f246e31f071690ffb1c8f41d21c4cddbad8bb99bf53d9ac6c982',
transactionIndex: 0,
blockHash: '0x297ed89cf22d78956e019100fd15ece49882124ba6d23476c4e48914d3da35f3',
blockNumber: 42,
gasUsed: 129230,
cumulativeGasUsed: 129230,
contractAddress: null,
logs: [ [Object] ],
status: '0x01',
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000008000000000000000000000002000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000' },
logs:
[ { logIndex: 0,
transactionIndex: 0,
transactionHash: '0x6502bd013b41f246e31f071690ffb1c8f41d21c4cddbad8bb99bf53d9ac6c982',
blockHash: '0x297ed89cf22d78956e019100fd15ece49882124ba6d23476c4e48914d3da35f3',
blockNumber: 42,
address: '0x8f0483125fcb9aaaefa9209d8e9d7b9c8b9fb90f',
type: 'mined',
event: 'CountryEvent',
args: [Object] } ] }
This is transaction receipt you can see that our country event gets fired too. Whenever you change blockchain state, it has to be a transaction and transactions consume gas
.
Now let’s check our entry by running this command
crud.getCountry("USA");
You should see a result something like this.
[ 'USA', 'Trump', BigNumber { s: 1, e: 7, c: [ 30000000 ] } ]
You’ve now learned how to interact with smart contract, and how to test it!
Show me what you’ve built in the comment section.
Conclusion
We have learned how to do basic CRUD operations using solidity and test our smart contract. We cut down on details which can be overwhelming for the sake of brevity. Solidity and Truffle have extensive documentation and you should read them. Also, we used web3.js which comes with Truffle bundle.
There are multiple ways to optimize our CRUD operations (Hint : you can use an external array). Optimize it and let us know.
It’s time for some 👏.
Starting a new blockchain project, or looking for a Solidity developer?
Crowdbotics helps business build cool things with Solidity (among other things). If you have a blockchain project where you need additional developer resources, drop us a line. Crowbotics can help you estimate build time for given product and feature specs, and provide specialized Solidity developers as you need them. If you’re building with Solidity, check out Crowdbotics.