1

I've been using truffle for unit testing and I can't find a way to execute two excludent tests. I mean, I'm creating an ICO contract and my tests depend on lower and upper cap limit, start and end blocks. Sometimes when I execute a series of tests I would need to restart the blockchain (of course only possible in dev chain) to be able to execute the other tests and I don't know how to do this or if this is possible.

I'm using truffle + testrpc for unit testing.

Here is one example of two tests that can't happen at the same test flow:

it("User trying to send eth after max pre ico cap reached by last user", function () {
return AuctusPreIco.deployed().then(function (instance) {
  // send a 5 eth transaction from user test account to contract
  var account = web3.eth.accounts[3]
  return instance.sendTransaction({ from: account, value: web3.toWei(3, "ether") })
    .then(assert.fail)
    .catch(function (error) {
      if (invalidOpCodeException(error)) {
        assert(
          true, 'max cap reached. Can\'t send more eth to contract.'
        )
      }
      else {
        unexceptedException(error)
      }
    })
  })
})

and

it("Sending eth after ico max block limit", function () {
return AuctusPreIco.deployed().then(function (instance) {
  // send a 5 eth transaction from user test account to contract
  var account = web3.eth.accounts[4]
  return instance.revoke({from: account})
    .then(assert.fail)
    .catch(function (error) {
      if (invalidOpCodeException(error)) {
        assert(
          true, 'revoke not allowed yet'
        )
      }
      else {
        unexceptedException(error)
      }
    })
  })
})

So, I don't know if I was clear enough, but if the max cap was already reached, the second test that tests if it will fail because of the max block limit wouldn't throw anyway.

How can I deal with this scenario? I want to execute all tests in a row.

2

The easiest way is to have two contract sections, since for each one your contracts redeployed a new.

contract('Contract test max', function(accounts) {
  it("Test max", async function() {
    const instance = await MyContract.deployed();
    // test max
  });
});
contract('Contract test min', function(accounts) {
  it("Test min", async function() {
    const instance = await MyContract.deployed();
    // test min
  });
});

Another approach is to have your deploy function invoked for each test

function MyDeploy() {
  return MyContract.new("parameters");
}
contract('Contract test', function(accounts) {
  it("Test max", async function() {
    const instance = await MyDeploy();
    // test max
  });
  it("Test min", async function() {
    const instance = await MyDeploy();
    // test min
  });
});
  • Hi Ismael, thanks for your response. I think the only way to do that is by having a new version of the contract as you suggested and passing parameters to it so that I can increase the last block height. My problem is that I have the parameters in the contract hard coded (for auditing purposes, we think having the parameters hard coded makes it easier to understand and validate). We are not using parameters in the constructor, therefore I can't change any variable from the contract. Is that a way to use the snapshot functionality from testrpc for this purpose? – Guilherme Gusman Jul 30 '17 at 17:15
  • Without knowing your contract is hard to tell what is best for you. I'd say setting the parameters in the constrtuctor is the cleanest way. You should audit the deployed contract anyway. Other option is to have two separate contract each with his own parameters, but with more than a couple of contracts is really hard to maintain. – Ismael Jul 30 '17 at 19:43
  • Thanks for your response! That's true! I ended up creating two separed test files and running them separately. – Guilherme Gusman Jul 30 '17 at 20:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.