Unit Testing in Truffle

my solution to the delete person assignment:

const People = artifacts.require("People");
const truffleAssert = require("truffle-assertions");

contract("People", async function(accounts){

  it("shouldn't allow non owner to delete person", async function(){
    instance = await People.deployed();
    instance.createPerson("fish", 20, 180, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.deletePerson(accounts[1], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);

  });

  it("should allow owner to delete user", async function(){
    instance = await People.new();
    await instance.createPerson("asf", 25, 120, {from: accounts[2], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.passes(instance.deletePerson(accounts[2], {from: accounts[0]}));
  });
});

2 Likes

My solution to the last unit testing task:

const People = artifacts.require("People");
const truffleAssert = require("truffle-assertions");

contract("People", async function(accounts){

  let instance;

  before(async function(){
    instance = await People.deployed()
  });

  it("shouldn't create a person with age over 150 years", async function(){
    await truffleAssert.fails(instance.createPerson("Bob", 200, 190, {value: web3.utils.toWei("1", "ether")}), truffleAssert.ErrorType.REVERT);
  });
  it("shouldn't create a person without payment", async function(){
    await truffleAssert.fails(instance.createPerson("Bob", 50, 190, {value: 1000}), truffleAssert.ErrorType.REVERT);
  });
  it("should set senior status correctly", async function(){
    await instance.createPerson("Bob", 65, 190, {value: web3.utils.toWei("1", "ether")});
    let result = await instance.getPerson();
    assert(result.senior === true, "Senior level not set");
  });
  it("should set age correctly", async function(){
    let result = await instance.getPerson();
    assert(result.age.toNumber() === 65, "Age not set correctly");
  });
  it("should not allow non-owner to delete people", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Lisa", 35, 160, {from: accounts[2], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.deletePerson(accounts[2], {from: accounts[2]}), truffleAssert.ErrorType.REVERT);
  });
  it("should allow the owner to delete people", async function(){
    let instance = await People.new();
    await instance.createPerson("Lisa", 35, 160, {from: accounts[2], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.passes(instance.deletePerson(accounts[1], {from: accounts[0]}));
  });
  it("should increase and correctly update balance when person is added and it matches to the balance on the blockchain", async function(){
    let instance = await People.new();
    let balanceAfterAdd = 1;
    await instance.createPerson("Lisa", 35, 160, {from: accounts[3], value: web3.utils.toWei("1", "ether")})
    await truffleAssert.passes(instance.balance === balanceAfterAdd && instance.balance === web3.eth.getBalance(0xc6a2c1ef58b4745729ef051173409ac40c3363c4));
  });
  it("should let the owner withdraw the balance of the contract", async function(){
    let instance = await People.new();
    await truffleAssert.passes(instance.withdrawAll({from: accounts[0]}));
  });
  it("shouldnt allow non owner to withdraw the balance of the contract", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Lisa", 35, 160, {from: accounts[4], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.withdrawAll({from: accounts[4]}), truffleAssert.ErrorType.REVERT);
  });
  it("should reset the balance to 0 after the withdrawal and should match to the balance of the blockchain", async function(){
    let instance = await People.new();
    let balanceAfterReset = 0;
    await instance.createPerson("Lisa", 35, 160, {from: accounts[5], value: web3.utils.toWei("1", "ether")});
    await instance.createPerson("Lisa", 36, 160, {from: accounts[6], value: web3.utils.toWei("1", "ether")});
    await instance.withdrawAll({from: accounts[0]});
    await truffleAssert.passes(instance.balance === balanceAfterReset && instance.balance === web3.eth.getBalance(0xc6a2c1ef58b4745729ef051173409ac40c3363c4));
  });
  it("should update the balance of the owner", async function(){
    let instance = await People.new();
    await instance.createPerson("Lisa", 35, 160, {from: accounts[7], value: web3.utils.toWei("1", "ether")});
    let balanceBefore = web3.eth.getBalance(accounts[0]);
    await instance.withdrawAll({from: accounts[0]});
    let balanceAfter = web3.eth.getBalance(accounts[0]);
    await truffleAssert.passes(balanceAfter > balanceBefore);
  });
});

//1. check when person is added, the balance of the contract gets increased AND it matches to what is registered to the balance that is registered to the contract address on the blockchain
//2. the contract owner can withdraw the ballance AND ballance is reduced to 0 and it matches to the blockchain AND owners balance is increased

//web3.eth.getBalance(address) -> query eth blockchain for the balance of a specific address (needed for comparing balance variable and real contract balance)
//need to find contract address in truffle

Hi @illyushin
In your test:

  • “should allow the owner to delete people”
    You are creating a new contract instance with People.new() and adding a person with the account[2], but you are actually deleting the account[1] so i m not sure this test make sense.

  • “should increase and correctly update balance when person is added and it matches to the balance on the blockchain”
    You can test it with a static value (let balanceAfterAdd = 1;) it ll work but to make sure the balance is indeed added. It’s better to store the balance of your contract before and after creating a person.
    in your assert what is “0xc6a2c1ef58b4745729ef051173409ac40c3363c4” ? As your contract will be deployed multiple times the address will change, instance.balance will give you the right result, no need to double check if web3 js api works :wink:

Edit:typo

1 Like

Here is my answer to the Owner Test Assignment:

it("should only allow owner to delete person", async function(){
    let createOptions = {
        value: web3.utils.toWei("1", "ether"),
        from: accounts[1]
    };

    await truffleAssert.passes(instance.createPerson("Bob", 50, 190, createOptions));
    await truffleAssert.fails(instance.deletePerson(accounts[0], accounts[2]));
    await truffleAssert.passes(instance.createPerson("Alice", 55, 190, createOptions));
    await truffleAssert.passes(instance.deletePerson(accounts[1], {from: accounts[0]}));
  });

Hi @PedroDiogo

In your first deletePerson test you are passing two parameters to your function (which is not correct)

await truffleAssert.fails(instance.deletePerson(accounts[0], accounts[2]));

I think you should test this function by calling it with an account which is not the owner using ‘from’.
In your second test you are doing it the right way.

Hey,

Thanks a lot. That is true. I’ve did fix it in later though :slight_smile:

Cheers!

1 Like

My Owner Test Assignment Solution:

  it("should only be deleted by the owner", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Bob", 50, 190, {value: web3.utils.toWei("1", "ether")});
    // Let's try deleting Bob (account[0]) through account[1]:
    await truffleAssert.fails(instance.deletePerson(accounts[0], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
  });
1 Like

And here is my Value Assignment Solution. Not so sure about this one so commented step by step in case someone wants to take a look. All tests passed and tried to trick them and still look solid. I was expecting to see any changes on the Balance in Peoples’ Contract in Ganache but nothing, that’s why I am not so sure about my code:

const People = artifacts.require("People");
const truffleAssert = require("truffle-assertions");

contract("People", async function(accounts){

  let instance;

  before(async function(){
    instance = await People.deployed();
  });
  it("should match the balance on the blockchain", async function(){
    // Let's reset the contract and create a person:
    let instance = await People.new();
    await instance.createPerson("Bob", 50, 190, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
    // Create a variable that gets the balance from the contract:
    let contractBalance = await instance.balance();
    // Assert that it should be the same as the balance on the blockchain:
    assert(contractBalance = await web3.eth.getBalance(instance.address), "balance should be the same");
  });
  it("should increase the balance", async function(){
    // Create a variable with the value of ether sent to the contract:
    let balanceAfterCreation = 1;
    // Assert that the new balance should have been increases to 1(balanceAfterCreation):
    assert(instance.balance = balanceAfterCreation, "balance should increase to 1");
  });
  it("should withdraw balance", async function(){
    // Let's try to use the owner (accounts[0]) to withdraw the funds, using the function withdrawAll:
    await truffleAssert.passes(instance.withdrawAll({from: accounts[0]}));
  });
  it("should be zero", async function(){
    instance = await People.deployed();
    // Let's create again a variable that gets the balance from the contract:
    let contractBalance = await instance.balance();
    // Create a variable with the value zero (which should be the balance after withdraw):
    let balanceAfterWithdraw = 0;
    // And assert that they have the same value:
    assert(balanceAfterWithdraw = contractBalance, "balance should be 0");
  });
  it("should be increased", async function(){
    // Let's create a variable which represents the balance of the owners contract after the withdraw:
    let ownersBalanceAfterWithdraw = 1;
    // And assert it is the same as the balance of accounts[0]:
    assert(ownersBalanceAfterWithdraw = await web3.eth.getBalance(accounts[0]), "owners balance should be 1");
  });
});

Hi @pedromndias

In your assert tests you are not testing the balance of the contract you are assigning a value.

Your = should be ==

assert(contractBalance = await web3.eth.getBalance(instance.address), "balance should be the same");

1 Like

Hey @gabba, thanks for your reply. Good point, didn’t pay attention to that detail and now changing “=” to “==” it’s a failing festival lol:

3 passing (3s)
 2 failing

Contract: People
      should increase the balance:
    AssertionError: balance should increase to 1
     at Context.<anonymous> (test\peopletest.js:91:5)
     at runMicrotasks (<anonymous>)
     at processTicksAndRejections (internal/process/task_queues.js:97:5)

 2) Contract: People
      should be increased:
    AssertionError: owners balance should be 1
     at Context.<anonymous> (test\peopletest.js:111:5)
     at runMicrotasks (<anonymous>)
     at processTicksAndRejections (internal/process/task_queues.js:97:5)

My second and fifth test are claming some error on the assert function line, any thoughts?
Thanks once again!

Hi @pedromndias
Hum try to do your async call outside of your assert and store it into a variable.
Don’t hesitate to console.log the result before testing it if you need to debug it

1 Like

Owner Test assignment :

const People=artifacts.require(“People”);
const truffleAssert=require(“truffle-assertions”);
contract(“People”,async function(accounts){
it("delete people function is availible for owner only! ", async function(){
let instance = await People.deployed();
await instance.createPerson(“Bob”, 40, 90, {from: accounts[2], value: web3.utils.toWei(“1”, “ether”)});
await truffleAssert.fails(instance.deletePerson(accounts[2], {from: accounts[2]}), truffleAssert.ErrorType.REVERT);
});
it(“Only owner can delete person”, async function(){
let instance = await People.new();
await instance.createPerson(“Bob”, 40, 90, {from: accounts[2], value: web3.utils.toWei(“1”, “ether”)});
await truffleAssert.passes(instance.deletePerson(accounts[1], {from: accounts[0]}));
});
});

1 Like

Value asignment
it(“Balance is increase after adding new Person”, async function(){
let instance = await People.deployed();
let Balance = await web3.eth.getBalance(People.address);
await instance.createPerson(“Lisa”, 28, 166, {value: web3.utils.toWei(“1”,“ether”), from: accounts[1]});
let newBalance = await web3.eth.getBalance(People.address);
assert(newBalance == parseInt(Balance) + parseInt(web3.utils.toWei(“1”,“ether”)));

});
it(“It is imposible widrow founds from contract if you are not owner”, async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.withdrawAll({from: accounts[1]}));
});
it("Conract owner is able widrow founds ", async function(){
let instance = await People.deployed();
await truffleAssert.passes(instance.withdrawAll({from: accounts[0]}));
});

1 Like

8 posts were merged into an existing topic: Introduction to Unit Testing

it("contract address balance", async function(){
    let instance = await People.deployed();
    let address = instance.address;
    let currentBalance = await web3.eth.getBalance(address);
   let currentbalanceInNumber = parseInt(currentBalance);
    await instance.createPerson("Lisa", 35, 160, {from: accounts[3], value: web3.utils.toWei("1", "ether")});
     currentbalanceInNumber += 1000000000000000000;
     let finalBalance = await web3.eth.getBalance(address);
     let finalBalanceInNumber = parseInt(finalBalance);
     
     assert(currentbalanceInNumber === finalBalanceInNumber, "cost not transfer correctly");
    });
   
    it("should withdraw all", async function(){
        let instance = await People.deployed();
        let ownerBalance = await web3.eth.getBalance(accounts[0]);
        let contractBalance = await web3.eth.getBalance(instance.address);
        ownerBalance = parseInt(ownerBalance) + parseInt(contractBalance);
        let txnReceipt = await instance.withdrawAll();
        let gasUsed = txnReceipt.receipt.gasUsed;
        gasUsed = parseInt(gasUsed)*20000000000;
        ownerBalance -= gasUsed;
        let address = instance.address;
        let currentBalance = await web3.eth.getBalance(address);
        let currentbalanceInNumber = parseInt(currentBalance);
        let finalOwnerBalance = await web3.eth.getBalance(accounts[0]);
        let finalBalanceInNumber = parseInt(finalOwnerBalance);

        assert((currentbalanceInNumber === 0) && (ownerBalance === finalBalanceInNumber),"transfer not set correctly");
      });type or paste code here
1 Like

Very nice! You even combined them all… I like it. :+1:
Ivo

1 Like

Owner test assignment ::

const People = artifacts.require(‘People’);
const truffleAssert = require(‘truffle-assertions’);

contract(‘People’, async function(accounts) {
it(“shouldn’t create a person with age over 150 years”, async function() {
let instance = await People.deployed();
await truffleAssert.fails(instance.createPerson(‘Bob’,200,190, {value: web3.utils.toWei(‘1’, ‘ether’)}),truffleAssert.ErrorType.REVERT);
});

it(‘should not create a person without payment’, async function() {
let instance = await People.deployed();
await truffleAssert.fails(instance.createPerson(‘Bob’,50,190, {value: 1000}),truffleAssert.ErrorType.REVERT);
});

it(‘should set senior status correctly’, async function() {
let instance = await People.deployed();
await instance.createPerson(‘Bob’,70,190, {value: web3.utils.toWei(‘1’, ‘ether’)});
let result = await instance.getPerson();
assert(result.senior === true, ‘Senior level not set’);
});

it(‘should set age correctly’, async function() {
let instance = await People.deployed();
let result = await instance.getPerson();
assert(result.age.toNumber() === 70, ‘Age not set correctly’);
});

it(‘should not allow deletion of person if not owner’, async function() {
let instance = await People.deployed();
let result = await instance.getCreator(0);
await instance.deletePerson(result);
assert.equal(result, accounts[0], ‘Incorrect person deleted’);
})

});

1 Like

my solution is

... some other testcases ....

    it("should only be possible for the owner to delete a person",
        async function(){
          let i = await People.deployed();
          await i.createPerson("CBob", 65, 190,
            {value:web3.utils.toWei("1","ether"), from: account[1]});
          await truffleAssert.fails(
                i.deletePerson(account[1], {from:account[2]})
                , truffleAssert.ErrorType.REVERT);
        });

    it("should be possible to delete person by owner",
        async function(){
          let i = await People.deployed();
          await i.deletePerson(account[0], {from:account[0]});
          let person = await i.getPerson();
          assert(person.name ==="" && person.age == 0 && person.height == 0 && person.senior == false);
        });
....
1 Like
const  People = artifacts.require("People");
const truffleAssert = require("truffle-assertions");

contract("People", async function(accounts){
  it("should allow the owner to delete the contract", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Bob", 65, 190, {value: web3.utils.toWei("1", "ether"), from: accounts[0]});
    await truffleAssert.passes(instance.deletePerson(accounts[0], {from: accounts[0]}), truffleAssert.ErrorType.REVERT);
  });
  it("should forbid a non-owner to delete the contract", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Bob", 65, 190, {value: web3.utils.toWei("1", "ether"), from: accounts[0]});
    await truffleAssert.fails(instance.deletePerson(accounts[0], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
  });
});
1 Like

Value assignment:

  it("should increase balance variable when a person is added", async function(){
    let instance = await People.new();
    await instance.createPerson("Bob", 65, 190, {value: web3.utils.toWei("1", "ether")});
    let balance = await instance.balance();
    assert(balance == web3.utils.toWei("1", "ether"), "balance not set correctly");
    await instance.createPerson("Alice", 45, 170, {value: web3.utils.toWei("4", "ether")});
    balance = await instance.balance();
    assert(balance == web3.utils.toWei("5", "ether"), "balance not set correctly");
  });
  it("should increase balance on the blockchain when a person is added", async function(){
    let instance = await People.new();
    await instance.createPerson("Bob", 65, 190, {value: web3.utils.toWei("1", "ether")});
    let balance = await web3.eth.getBalance(instance.address);
    assert(balance == web3.utils.toWei("1", "ether"), "balance not set correctly");
    await instance.createPerson("Alice", 45, 170, {value: web3.utils.toWei("4", "ether")});
    balance =  await web3.eth.getBalance(instance.address);
    assert(balance == web3.utils.toWei("5", "ether"), "balance not set correctly");
  });
  it("balance on the blockchain and balance variable should be the same", async function(){
    let instance = await People.new();
    await instance.createPerson("Bob", 65, 190, {value: web3.utils.toWei("1", "ether")});
    let balance1 = await instance.balance();
    let balance2 = await web3.eth.getBalance(instance.address);
    assert(balance1 == balance2, "balance not set correctly");
    await instance.createPerson("Alice", 45, 170, {value: web3.utils.toWei("4", "ether")});
    balance1 =  await instance.balance();
    balance2 =  await web3.eth.getBalance(instance.address);
    assert(balance1 == balance2, "balance not set correctly");
  });
1 Like