Unit Testing in Truffle

Posting solution for owner test assignment.

There are two tests, one for testing that the person gets deleted and one for testing that only the owner can delete a person

it("should erase person  correctly",
  async function(){
    let instance=await People.deployed();
    let addressCreator= await instance.getCreator(0);
    await instance.deletePerson(addressCreator);
    let resultAfter= await instance.getPerson();
    assert(resultAfter.name === "" && resultAfter.age.toNumber()===0 && resultAfter.height.toNumber()===0);
  });
  it("should't delete person without owner permission",
  async function(){
    let instance=await People.deployed();
    let addressCreator= await instance.getCreator(0);
    await truffleAssert.fails(instance.deletePerson(addressCreator,{from: accounts[1]}));
  });

Taking into account that we need : contract(“People”, async function(accounts)…
to access accounts.

thanks :slight_smile:

Took me a long time to figure out that “accounts” is an argument in the top function header and not in each individual test, but here we go:

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 ("shouldn't 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", 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 instance = await People.deployed();
    let result = await instance.getPerson();
    assert(result.age.toNumber() === 65, "Age not set correctly");
  });
  it("should not let a non-owner delete a person", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Larry", 50, 100, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.deletePerson(accounts[1], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
  });
  it("should let the owner delete a person", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Shelly", 50, 100, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.passes(instance.deletePerson(accounts[1], {from: accounts[0]}), truffleAssert.ErrorType.REVERT);
  })
});
2 Likes

It happened the same thing to me. Later, just for fun I tried to “play” with
the function in each individual test, but did’t get any results. I don’t know what kind of arguments this function can accept.

1 Like

I created 4 tests
1 - Make sure contract balance increases when a new person is created
2 - Owner can withdraw
3 - Non-owner cannot withdraw
4 - Contract balance at 0 after withdrawal

Update: I was able to test with truffle develop. I am getting the following errors. It looks like it doesn’t like the contract address which I got from Ganache

8 passing (2s)
2 failing

  1. Contract: People
    should increase the contract balance when a person is created:
    Error: Provided address “1.3319270638314048e+47” is invalid, the capitalization checksum test failed, or its an indrect IBAN address which can’t be converted.
    at Method.inputAddressFormatter (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-helpers/src/formatters.js:409:1)
    at /usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-method/src/index.js:144:1
    at Array.map ()
    at Method.formatInput (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-method/src/index.js:142:1)
    at Method.toPayload (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-method/src/index.js:177:1)
    at Eth.send [as getBalance] (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-method/src/index.js:467:1)
    at Context. (test/PeopleTest.js:43:51)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)

  2. Contract: People
    should decrease contract balance to 0 after withdrawl:
    Error: Provided address “1.3319270638314048e+47” is invalid, the capitalization checksum test failed, or its an indrect IBAN address which can’t be converted.
    at Method.inputAddressFormatter (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-helpers/src/formatters.js:409:1)
    at /usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-method/src/index.js:144:1
    at Array.map ()
    at Method.formatInput (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-method/src/index.js:142:1)
    at Method.toPayload (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-method/src/index.js:177:1)
    at Eth.send [as getBalance] (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3-core-method/src/index.js:467:1)
    at Context. (test/PeopleTest.js:62:28)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)

   it("should increase the contract balance when a person is created", async function(){
    let instance = await People.new();
    let originalBalance = parseInt(await web3.eth.getBalance(0x17549148CF6eB8138256997bDB6d1D564Ed8Bd56));
    await instance.createPerson("Shelly", 50, 100, {value: web3.utils.toWei("1", "ether")});
    let newBalance = parseInt(await web3.eth.getBalance(0x17549148CF6eB8138256997bDB6d1D564Ed8Bd56));
    assert(newBalance > originalBalance, "Contract balance was not increased when person created");
  });
  it("should let the owner withdraw balance", async function(){
    let instance = await People.new();
    await instance.createPerson("Shelly", 50, 100, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.passes(instance.withdrawAll({from: accounts[0]}));
  });
  it("should not let anyone other than owner withdraw balance", async function(){
    let instance = await People.new();
    await instance.createPerson("Shelly", 50, 100, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.withdrawAll({from: accounts[1]}), truffleAssert.ErrorType.REVERT);
  });
  it("should decrease contract balance to 0 after withdrawl", async function(){
  let instance = await People.new();
  await instance.createPerson("Shelly", 50, 100, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
  await instance.withdrawAll();
  assert(parseInt(web3.eth.getBalance(0x17549148CF6eB8138256997bDB6d1D564Ed8Bd56)) == 0);
  });
});

When I tried to test these, I got this error and all of a sudden I cannot get back into the truffle console. Any help would be appreciated:

Could not connect to your Ethereum client with the following parameters:
    - host       > 127.0.0.1
    - port       > 7545
    - network_id > 5777
Please check that your Ethereum client:
    - is running
    - is accepting RPC connections (i.e., "--rpc" option is used in geth)
    - is accessible over the network
    - is properly configured in your Truffle configuration file (truffle-config.js)

Truffle v5.0.42 (core: 5.0.42)
Node v11.12.0```

Four tests regarding balances. The one I’m missing is about testing the equality between the variable balance in the contract and the balance in the blockchain. I’ll look at Philip’s answer.

it("should add one ether to contract after  creating first person",
  async function(){
    let instance= await People.new();
    await instance.createPerson("Oreo", 70, 190,{from: accounts[2],value:web3.utils.toWei("1","ether")});
    let  balance = await web3.eth.getBalance(instance.address);
    assert.deepEqual(balance, web3.utils.toWei("1","ether"),"1 ether not deposited  contract on first time a person is added");
  });

  it("only owner should be able to withdraw",
  async function(){
    let instance= await People.new();
    await instance.createPerson("Oreo", 70, 190,{from: accounts[2],value:web3.utils.toWei("1","ether")});
    await truffleAssert.fails(instance.withdrawAll({from:accounts[1]}));
  });

  it("owner can withdraw",
  async function(){
    let instance= await People.new();
    await instance.createPerson("Oreo", 70, 190,{from: accounts[2],value:web3.utils.toWei("1","ether")});
    await truffleAssert.passes(instance.withdrawAll({from:accounts[0]}));
  });

  it("should empty contract balance after withdraw",
  async function(){
    let instance= await People.new();
    await instance.createPerson("Oreo", 70, 190,{from: accounts[2],value:web3.utils.toWei("1","ether")});
    await instance.withdrawAll({from:accounts[0]});
    let contractBalance= await web3.eth.getBalance(instance.address);
    assert.deepEqual(contractBalance, "0");
  });

Hey @Flaflaflohi

Are you testing on your local blockchain? If yes you just need to navigate into your project main folder, then type

truffle develop

then, once truffle develop is active

test

Happy learning,
Dani

2 Likes

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

contract(“People”, async function(accounts){
it(“shouldn’t be possible to delete a person without being the contract owner”, async function(){
let instance = await People.deployed();
await instance.createPerson(“Dell”, 30, 210, {value: web3.utils.toWei(“1”,“ether”), from: accounts[2]});
await truffleAssert.fails(instance.deletePerson(accounts[2], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
});
it(“should be possible to delete a persen by the contract owner”, async function(){
let instance = await People.deployed();
//await instance.createPerson(“Dell”, 30, 210, {value: web3.utils.toWei(“1”,“ether”), from: accounts[2]});
await instance.deletePerson(accounts[2], {from: accounts[0]});
const {0: Name, 1: Age, 2: Height, 3: Senior} = await instance.getPerson({from: accounts[2]});
assert(Name === “” && Age == 0, “Person not deleted”);
});
});

  it("check if contract balance increases the same in instance and chain after adding a person", async function(){
    let instance = await People.deployed();
    let chain_balance_before = await web3.eth.getBalance(instance.address);
    let instance_balance_before = await instance.balance();
    await instance.createPerson("Chris", 24, 170, {value: web3.utils.toWei("1", "ether")});
    let chain_balance_after = await web3.eth.getBalance(instance.address);
    let instance_balance_after = await instance.balance();
    assert(chain_balance_after - chain_balance_before == web3.utils.toWei("1", "ether") &&
      instance_balance_after - instance_balance_before == web3.utils.toWei("1", "ether"), "Chain and Instance Balance did not increase the same");
  });
  it("nonOwner cannot withdraw", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Angela", 25, 154, {value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.withdrawAll({from: accounts[1]}), truffleAssert.ErrorType.REVERT);
  });
  it("theOwner can withdraw", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Peter", 32, 187, {value: web3.utils.toWei("1", "ether")});
    await truffleAssert.passes(instance.withdrawAll({from: accounts[0]}), truffleAssert.ErrorType.REVERT);
  });
  it("check if instance balance and chain balance match 0 after withdrawAll", async function(){    let instance = await People.deployed();
    await instance.createPerson("Karen", 32, 187, {value: web3.utils.toWei("1", "ether")});
    await instance.withdrawAll();
    assert(await web3.eth.getBalance(instance.address) == 0 && await instance.balance() == 0, "Error");
  });
  it("check if owner balance increased after withdrawAll", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Kim", 22, 165, {value: web3.utils.toWei("1", "ether")});
    let owner_balance = await web3.eth.getBalance(accounts[0]);
    await instance.withdrawAll();
    assert(await web3.eth.getBalance(accounts[0]) > owner_balance, "Error");
  });
1 Like

Ok, to be honest I confess that I fed up in here. Instead of passing the videos and not giving assignments and cheating i will be proud with my non-result-effort for now 'cos wanna move on. I will share my last screen before passing to the answer video, but this is not ending in here, I’ll come up later!
My test scenario was creating a person then pass the test by checking the withdraw amount is the same. Comments are open :eyes::droplet:

it("should check the withdrawAll will be handled correctly", async function(){

    let instance = await People.deployed();    

    await instance.createPerson("Leila", 24, 181, {from: accounts[0], value: web3.utils.toWei("1", "ether")});
    

    //var rightAmount = web3.eth.getBalance(instance.accounts[0]);

    //let balance = await instance.getBalance(accounts[0]);

    let balance = await instance.balance;

    //console.log("balance.toNumber(): " + balance.toNumber());

    console.log("balance: " + balance);

    

    truffleAssert.passes(await instance.withdrawAll( balance ));

    /* 
    var sc;
    People.new().then(function(res) { 
      sc = People.at(res.address);
    });
    console.log("sc.addres: " + sc.address);
     */

    //address()
    //await instance.withdrawAll();
    /* web3.eth.getBalance(address(owner), number, function(error, result) {
      if (error) {
        truffleAssert.ErrorType.REVERT
      } else {
        return result;
      } 
    });*/
  });
1 Like

trying to find a person in account which don’t exist throws: truffleAssert.ErrorType.AssertionError, so if that error come I know the person is deleted

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

it("should set senior status correctly", async function(){
    let instance = await People.deployed();
    await instance.createPerson("gote",65,200, {value: web3.utils.toWei("1","ether"),from: accounts[0]});
    let result = await instance.getPerson();
    assert(result.senior === true, "senior level not set");
  });
  it("should't delete a person if not owner", async function(){
    let instance = await People.deployed();
    await truffleAssert.fails(instance.deletePerson(accounts[0],{from:accounts[1] }), truffleAssert.ErrorType.REVERT);
  });
  it("should delete person when owner", async function(){
    let instance = await People.deployed();
    await instance.deletePerson(accounts[0],{from:accounts[0] }), truffleAssert.ErrorType.REVERT;
    await truffleAssert.fails(instance.getPerson(accounts[0]), truffleAssert.ErrorType.AssertionError);

  });

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

const oneEther = web3.utils.toWei("1", "ether");

contract("People", async (accounts) => {
  let instance;

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

  it("Should not allow to delete person if not owner", async () => {
    const owner = accounts[0];
    const someoneElse = accounts[1];

    await truffleAssert.reverts(
      instance.deletePerson(owner, { from: someoneElse })
    );
  });

  it("Should delete person and emit event", async () => {
    const creator = accounts[2];
    const owner = accounts[0];

    let instance = await People.new();

    const name = "Person ToBeDeleted";
    await instance.createPerson(name, 10, 120, {
      from: creator,
      value: web3.utils.toWei("1", "ether"),
    });

    const result = await instance.deletePerson(creator, { from: owner });
    truffleAssert.eventEmitted(result, "personDeleted", { name });
  });

  it("after creating a person, the contract balance should be increased by 1 ether", async () => {
    let instance = await People.new();
    const contractAddress = instance.address;

    const initialBalance = await web3.eth.getBalance(contractAddress);
    assert(initialBalance === "0", "Initial balance should be 0");

    await instance.createPerson("Satoshi", 11, 170, {
      value: web3.utils.toWei("1", "ether"),
    });

    const balanceAfterCreation = await web3.eth.getBalance(contractAddress);
    assert(balanceAfterCreation === oneEther);
  });

  it("contract balance should be withdrawable by the owner", async () => {
    let instance = await People.new();
    const owner = accounts[0];

    await instance.createPerson("Satoshi", 11, 170, {
      value: web3.utils.toWei("1", "ether"),
    });

    const initialOwnerBalance = parseFloat(await web3.eth.getBalance(owner));

    await truffleAssert.passes(instance.withdrawAll());

    const ownerBalanceAfterWithdrawal = parseFloat(
      await web3.eth.getBalance(owner)
    );

    assert(
      ownerBalanceAfterWithdrawal > initialOwnerBalance,
      "Owner balance should be greater than it was before withdrawing"
    );
  });

  it("contract balance should not be withdrawable by others", async () => {
    let instance = await People.new();

    await instance.createPerson("Satoshi", 11, 170, {
      value: web3.utils.toWei("1", "ether"),
    });

    await truffleAssert.reverts(instance.withdrawAll({ from: accounts[1] }));
  });

  it("after withdrawing all, the contract balance should be 0", async () => {
    let instance = await People.new();
    const contractAddress = instance.address;

    await instance.createPerson("Satoshi", 11, 170, {
      value: web3.utils.toWei("1", "ether"),
    });

    await instance.withdrawAll();

    const contractBalance = await web3.eth.getBalance(contractAddress);

    assert(
      contractBalance === "0",
      "Contract balance should be 0 after owner withdraws all"
    );
  });

  it("balance stored as local variable matches balance on the blockchain", async () => {
    let instance = await People.new();

    const checkBalanceVarsAreSame = async () => {
      const blockchainBalance = parseFloat(
        await web3.eth.getBalance(instance.address)
      );
      const localBalance = (await instance.balance()).toNumber();
      return blockchainBalance === localBalance;
    };

    const initialBalancesMatch = await checkBalanceVarsAreSame();
    assert(initialBalancesMatch === true, "Initial balances should match");

    await instance.createPerson("Satoshi", 11, 170, {
      value: web3.utils.toWei("1", "ether"),
    });
    // checking balances matching here gives "Error: Number can only safely store up to 53 bits"
    // await checkBalanceVarsAreSame();

    await instance.withdrawAll();

    const balancesMatchAfterWithdrawal = await checkBalanceVarsAreSame();
    assert(
      balancesMatchAfterWithdrawal === true,
      "Balances should match after withdrawal"
    );
  });
});

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

contract("People", async function(accounts){
  let instance;
  let ownerAcc = accounts[0];
  let userAcc =  accounts[1];

  it("should allow the owner to delete person", async function(){
    instance = await People.deployed();
    await instance.createPerson("Mar.io", 52, 180, {from: userAcc, value: web3.utils.toWei("1", "ether")});
    await truffleAssert.passes(instance.deletePerson(userAcc, {from: ownerAcc}));
  });

  it("shouldn't allow the user to delete person", async function(){
    await instance.createPerson("Mar.io", 52, 180, {from: userAcc, value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.deletePerson(userAcc, {from: userAcc}));
  });
});
1 Like

Value assignment

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

contract("People", async function(accounts){
  let instance;
  let ownerAcc = accounts[0];
  let userAcc =  accounts[3];
  let payment = web3.utils.toWei("1", "ether");

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

  it("should validate increase in contact balance", async function(){
    await instance.createPerson("Mar.io", 52, 180, {from: userAcc, value: payment});
    let contractBalance = await web3.eth.getBalance(instance.address);
    let variableBalance = await instance.balance();
    assert(contractBalance == variableBalance, "Problem with contract balance" + contractBalance + " " + variableBalance);
    assert(variableBalance == payment, "Problem with contract balance value" + variableBalance + " " + payment);
  });

  it("should validate balance after withrawal", async function(){
    await instance.withdrawAll({from: ownerAcc});
    let contractBalance = await web3.eth.getBalance(instance.address);
    let variableBalance = await instance.balance();
    assert(contractBalance == variableBalance, "Problem with contract balance" + contractBalance + " " + variableBalance);
    assert(variableBalance == 0, "Problem with contract balance value" + variableBalance);
  });
});
1 Like

Hi guys,

Any ideas why I am encountering this error?

Thanks.

Fixed it already, turns out I was using a newer version of Truffle. Had to reinstall the 5.0.42 version (not sure how I did it but it works fine now)

1 Like

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


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

  it("should not allow  a non-creator/owner of the person entry to delete the person", async function(){
    let instance = await People.deployed();
    await instance.createPerson( "micky", 22, 160, { value: web3.utils.toWei("1", "ether"), from: accounts[3] });
    await truffleAssert.fails( instance.deletePerson( accounts[3], { from: accounts[3]} ), truffleAssert.ErrorType.REVERT);
  });
  
  it("should allow the creator/owner of the person entry to delete the person", async function(){
    let instance = await People.deployed();
    await instance.createPerson( "Max", 21, 160, { value: web3.utils.toWei("1", "ether"), from: accounts[2] });
    await truffleAssert.passes( instance.deletePerson( accounts[2], { from: accounts[0]}));
1 Like

Hello, here’s my code (removed the first three tests from the video):

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

contract("People", async function(accounts){
  
  it("Should allow owner to delete a person", async function(){
    let instance = await People.deployed();
    await instance.createPerson("YoonSeri", 30, 160, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.passes(instance.deletePerson(accounts[1], {from: accounts[0]}));
  })

  it("Should not allow non-owners delete a person", async function(){
    let instance = await People.deployed();
    await instance.createPerson("JeongHyeok", 24, 160, {from: accounts[0], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.deletePerson(accounts[0], {from: accounts[2]}),truffleAssert.ErrorType.REVERT);
  })

  it("Should not allow non-owners access to creator list", async function(){
    let instance = await People.deployed();
    await instance.createPerson("SeoDan", 24, 160, {from: accounts[4], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.getCreator(4, {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
  })

  it("Should let owner see creator list", async function(){
    let instance = await People.deployed();
    await truffleAssert.passes(instance.getCreator(1, {from: accounts[0]}));
  })

  it("Should allow owner withdraw all balance", async function(){
    let instance = await People.deployed();
    await truffleAssert.passes(instance.withdrawAll({from: accounts[0]}));
  })

  it("Should not allow non-owners withdraw balance", async function(){
    let instance = await People.deployed();
    await truffleAssert.fails(instance.withdrawAll({from: accounts[3]}), truffleAssert.ErrorType.REVERT);
  })

  it("Should set the balance to zero after withdrawing all funds", async function(){
    let instance = await People.deployed();
    await instance.withdrawAll({from: accounts[0]});
    let balance = await instance.balance();
    assert(balance == 0, "Withdraw fail.");
  })
})
1 Like

Value assignment code:

  it("should increase owner account by 1 ether", async function(){
    let accountBefore = await instance.balance();
    await instance.createPerson("gote",65,200, {value: web3.utils.toWei("1","ether"),from: accounts[2]});
    let accountAfter = await instance.balance();
    let result = accountAfter - accountBefore - web3.utils.toWei("1","ether");
    await assert(result === 0 );

  });

  it("should show the same amount ether from inside contract as from web3", async function(){
    let accountWeb3 = await web3.eth.getBalance(instance.address);
    let accountOwner = await instance.balance();
    let result = accountWeb3 - accountOwner;
    await assert(result === 0 );
1 Like