Unit Testing in Truffle

Uhm wait but the 2nd one should not fail because you are calling the method deletePerson() from account[0] which is the owner.

Yes, but why accounts [0] and [1] or [5] have the same owner? My understanding is that if the owner tries to delete one of his accounts assertion should fail (pass the test) Because he is the owner.

My understanding is that if the owner tries to delete one of his accounts assertion should fail (pass the test) Because he is the owner.

This is not correct.
The owner of the contract is the account that deploys it.
By default, the account that deploys a contract is accounts[0] so the address associated to accounts[0] is the owner of the contract.
Accounts[0] is the only address that can call functions restricted to the owner therefore is the only account that can call the function deletePerson().

2 Likes

I saw other tests that were much more wordy so I hope this is not incomplete or lacking something! All tests passed.

it("should not let non-owner delete people", async function() {
        let instance = await People.deployed();
        await instance.createPerson("Ralph", 29, 200, {value: web3.utils.toWei("1", "ether"), from: accounts[0]});
        await truffleAssert.fails(instance.deletePerson(accounts[5], {from: accounts[5]}), truffleAssert.ErrorType.REVERT);    
    });

    it("should allow the owner to delete people", async function() {
        let instance = await People.deployed();
        await instance.createPerson("Ralph", 29, 200, {value: web3.utils.toWei("1", "ether"), from: accounts[0]});
        await truffleAssert.passes(instance.deletePerson(accounts[0], {from: accounts[0]}));
    });
1 Like

Hey guys, I’m need some help with with an error. I get this error when I enter migrate in the truffle console:

I followed the link and installed the solcjs compiler but I don’t know what else I need to do.
Thanks.

Hey @Andro

This FAQ will help you FAQ - How do change truffle version

Cheers,
Dani

1 Like

I added the accounts to the async function in the contract declaration.

it("Only Owner can deletePerson", async function(){
    let instance = await People.deployed();
    await truffleAssert.fails(instance.deletePerson(accounts[0], {from: accounts[1]}));
  });

  it("Owner can deletePerson", async function(){
    let instance = await People.deployed();
    await truffleAssert.passes(instance.deletePerson(accounts[0], {from: accounts[0]}));
  });
1 Like

Works, thank you Dani.

1 Like

@Andro happy to read that!
If you need help just ping me.

Happy learning,
Dani

1 Like
  it("Only owners may delete people", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Bob", 34, 123, {value: web3.utils.toWei("1", "ether"), from: accounts[0]});
    await truffleAssert.passes(instance.deletePerson(accounts[0], {from: accounts[0]}), truffleAssert.ErrorType.REVERT);
  });

  it("Non owners cannot delete people", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Bob", 34, 123, {value: web3.utils.toWei("1", "ether"), from: accounts[0]});
    await truffleAssert.fails(instance.deletePerson(accounts[1], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
  });
1 Like

Owner Test Assignment:

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

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

it("should not be able to delete person", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Jane", 30, 177, {value: web3.utils.toWei("1", "ether"), from: accounts[1]});
    await truffleAssert.fails(instance.deletePerson(accounts[1], {from:accounts[1]}));
  });

it("should be able to delete person", async function(){
      let instance = await People.deployed();
      await truffleAssert.passes(instance.deletePerson(accounts[1], {from:accounts[0]}));
    });
});

1 Like

Value assignment:


it("should increase balance by 1 ether" , async function(){
  instance = await People.new();
  await instance.createPerson("Jane", 30,177, {value: web3.utils.toWei("1", "ether")});
  let balance = await instance.balance();
  let oldBalance = await parseFloat(balance);
  let newBalance = await web3.eth.getBalance(People.address);
  assert(oldBalance == web3.utils.toWei("1", "ether"), oldBalance == newBalance);
});

it("should let owner withdraw balance", async function(){
  instance = await People.new();
  await instance.createPerson("Jane", 30,177, {value: web3.utils.toWei("1", "ether"), from:accounts[0]});
  await TruffleAssert.passes(instance.withdrawAll({from:accounts[0]}));

});
it("should not let non-owner withdraw balance", async function(){
  instance = await People.new();
  await instance.createPerson("Jane", 30,177, {value: web3.utils.toWei("1", "ether"), from:accounts[1]});
  await TruffleAssert.fails(instance.withdrawAll({from:accounts[1]}));
});

it("should reduce contract balance", async function(){
instance = await People.new();
await instance.createPerson("Jane", 30,177, {value: web3.utils.toWei("1", "ether")});
await instance.withdrawAll();
let balance = await instance.balance();
let oldBalance = await parseFloat(balance);
let newBalance = await web3.eth.getBalance(People.address);
assert(oldBalance == web3.utils.toWei("0", "ether"), oldBalance == newBalance);
});

it("should increase owners balance after withdrawal", async function(){
  instance = await People.new();
  await instance.createPerson("Jane", 30,177, {value: web3.utils.toWei("1", "ether")});
  let oldBalance = parseFloat (await web3.eth.getBalance(accounts[0]));
  await instance.withdrawAll();
  let newBalance = parseFloat (await web3.eth.getBalance(accounts[0]));
  assert(oldBalance<newBalance);
});
1 Like

Hello,
why do we create an instance for every testing condition? i.e let instance=await People.deployed()

1 Like

Owner test assignment:

contract("People", async function(accounts){
it("shouldn't be able to delete a persone if not owner", async function(){
        let instance = await People.deployed();
        await instance.createPerson("Bob", 65, 170, {value: web3.utils.toWei("1", "ether"), from: accounts[1]});
        await truffleAssert.fails(instance.deletePerson(accounts[1], {from: accounts[1]}),
        truffleAssert.ErrorType.REVERT);
    });
    it("should be able to delete a persone if owner", async function(){
        let instance = await People.deployed();
        await truffleAssert.passes(instance.deletePerson(accounts[1], {from: accounts[0]}),
        truffleAssert.ErrorType.REVERT);
    });
});
1 Like

Value assignment:

contract("People", async function(accounts){
it("should increase the balance after a createPerson function", async function(){
        let instance = await People.new();
        const previousBalance = parseFloat(await instance.balance());
        await instance.createPerson("Bob", 38, 180, {value: web3.utils.toWei("1", "ether")});
        let newBalance = parseFloat(await web3.eth.getBalance(instance.address));
        assert(previousBalance < newBalance, "Amount spent to createPerson hasn't been added to the balance.");
    });
    it("should only allow the owner to withdraw fund", async function(){
        let instance = await People.new();
        await instance.createPerson("Bob", 38, 180, {value: web3.utils.toWei("1", "ether")});
        await truffleAssert.passes(instance.withdrawAll({from: accounts[0]}));
    });
    it("shouldn't allow anyone who isn't the owner to withdraw fund", async function(){
        let instance = await People.new();
        await instance.createPerson("Bob", 38, 180, {value: web3.utils.toWei("1", "ether")});
        await truffleAssert.fails(instance.withdrawAll({from: accounts[1]}), truffleAssert.ErrorType.REVERT);
    });
    it("should have: balance = 0 after the withdrawAll function", async function(){
        let instance = await People.new();
        await instance.createPerson("Bob", 38, 180, {value: web3.utils.toWei("1", "ether")});
        await instance.withdrawAll();
        let previousBalance = parseFloat(await instance.balance());
        let newBalance = parseFloat(await web3.eth.getBalance(instance.address));
        assert(previousBalance == newBalance && previousBalance == web3.utils.toWei("0", "ether"), "The balance isn't equal to 0.");
    });
    it("should increase the owner balance after a withdraw", async function(){
        let instance = await People.new();
        await instance.createPerson("Bob", 38, 180, {value: web3.utils.toWei("1", "ether")});
        const previousBalance = parseFloat(await web3.eth.getBalance(accounts[0]));
        await instance.withdrawAll();
        let newBalance = parseFloat(await web3.eth.getBalance(accounts[0]));
        assert(previousBalance < newBalance, "the owner balance hasn't increased");
    });
});
1 Like

Hey @hashmiabrar1

That really depends if you need a new instance every time.
Personally most of the time I do not do that as I want that all my tests use the same instance so that I can check the whole ‘flow’ of my contract.

Cheers,
Dani

it("Balance of contact should increase by 1 ether", async function(){
    await instance.createPerson("Bob", 34, 123, {value: web3.utils.toWei("1", "ether")});
    let balance = await instance.balance();
    let oldBalance = await parseFloat(balance);
    let newBalance = await web3.eth.getBalance(People.address);
    assert(oldBalance == web3.utils.toWei("1", "ether"), oldBalance == newBalance);
  });

  it("Only owner can withdral balance", async function(){
    await instance.createPerson("Bob", 34, 123, {value: web3.utils.toWei("1", "ether")});
    await truffleAssert.passes(instance.withdrawAll({from: accounts[0]}));
  });

  it("Non-owners cannot withdrawl balance", async function(){
    await instance.createPerson("Bob", 34, 123, {value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.withdrawAll({from: accounts[1]}), truffleAssert.ErrorType.REVERT);
  });

  it("should reduce contract balance", async function(){
    await instance.createPerson("Bob", 34, 123, {value: web3.utils.toWei("1", "ether")});
    await instance.withdrawAll();
    let balance = await instance.balance();
    let floatBalance = await parseFloat(balance);
    let newBalance = await web3.eth.getBalance(People.address);
    assert(oldBalance == web3.utils.toWei("0", "ether"), floatBalance == newBalance);
  });

  it("should increase owners balance after withdrawal", async function(){
    await instance.createPerson("Bob", 34, 123, {value: web3.utils.toWei("1", "ether")});
    let oldBalance = parseFloat(await web3.eth.getBalance(accounts[0]));
    await instance.withdrawAll();
    let newBalance = parseFloat(await web3.eth.getBalance(accounts[0]));
    assert(oldBalance < newBalance);
  });

im a bit confused as why parseFloat is used. My understanding is that parsedFloat used to convert a string into an integer. When we use wei isnt the wei already an integer?. I tested the code without parseFloat and the test still works.

Hey @RCV

Correct no need to user parse float as Solidity does work with uint numbers :slight_smile:

Cheers,
Dani

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

contract("People", async function(accounts){
  it("should NOT be able to delete a person if not owner", async function(){
    let instance = await People.deployed();
    await instance.createPerson("Bob", 22, 190, {value: web3.utils.toWei("1", "ether"), from: accounts[2]});
    await truffleAssert.fails(instance.deletePerson(accounts[2], {from: accounts[2]}), truffleAssert.ErrorType.REVERT);
  });
  it("should be able to delete a person if owner", async function(){
    let instance = await People.deployed();
    await instance.createPerson("John", 22, 190, {value: web3.utils.toWei("1", "ether"), from: accounts[3]});
    await truffleAssert.passes(instance.deletePerson(accounts[3], {from: accounts[0]}));
  });
});
1 Like

This was a bit hard to understand, you have to keep the false positives and the positive false separated. :sweat_smile:
This is my code:

it("should not be able to delete person if not the owner", async function () {
        let instance = await People.deployed();
        await instance.createPerson("Bob", 50, 190, {value: web3.utils.toWei("1", "ether"),from: accounts[0]})
        let persn = await instance.getPerson({ from: accounts[0] });
        assert(persn.name === "Bob", "Person not created")
        await
            truffleAssert.fails(
            instance.deletePerson(accounts[0], { from: accounts[0] }
            ), truffleAssert.ErrorType.REVERT
            );
        let person = await instance.getPerson({from: accounts[0]});
        assert(person.name === "BoB", "Person deleted");

    });
    it("should not be able to delete person if not the owner", async function () {
      let instance = await People.deployed();
      await instance.createPerson("Bob", 50, 190, {
        value: web3.utils.toWei("1", "ether"),
        from: accounts[0],
      });
      let persn = await instance.getPerson({ from: accounts[0] });
      assert(persn.name === "Bob", "Person not created");
      await truffleAssert.fails(
        instance.deletePerson(accounts[0], { from: accounts[1] }),
        truffleAssert.ErrorType.REVERT
      );
      let person = await instance.getPerson({ from: accounts[0] });
      assert(person.name === "BoB", "Person deleted");
    });

and the last:

  /// ADD BALANCE CORRECTLY TO CONTRACT
  it("should increase balance on the contract", async function () {
    await instance.createPerson("Alice", 29, 160, {
      from: accounts[3],
      value: web3.utils.toWei("1", "ether"),
    });
    let bal1 = await instance.balance();
    let bal2 = await web3.eth.getBalance(instance.address);
    assert(parseFloat(bal1) === parseFloat(bal2), "Balance is not the same");
  });

  /// The owner of the contract can withdraw
  it("owner can withdraw from the contract", async function () {
    await instance.createPerson("Alice", 29, 160, {
      from: accounts[3],
      value: web3.utils.toWei("2", "ether"),
    });
    await truffleAssert.passes(
      instance.withdrawAll({ from: accounts[0] }),
      truffleAssert.ErrorType.REVERT
    );
  });

  ///Non-owner of the contract can not withdraw
  it("Non-owner can not withdraw from the contract", async function () {
    await instance.createPerson("Alice", 29, 160, {
      from: accounts[3],
      value: web3.utils.toWei("2", "ether"),
    });
    await truffleAssert.fails(
      instance.withdrawAll({ from: accounts[3] }),
      truffleAssert.ErrorType.REVERT
    );
  });

///Balance reset
  it("Balance should reset to 0 after withdrawal", async function () {
    await instance.createPerson("Alice", 29, 160, {
      from: accounts[4],
      value: web3.utils.toWei("1", "ether"),
    });
    await instance.withdrawAll();
    let bal2 = await instance.balance();
    assert(parseFloat(bal2) === 0, "Balance is not 0");
  });
1 Like