1

I just figured out how to deploy smart contracts on a test RPC with truffle. This is great! But when I do my tests, I am wondering how to keep the state of a deployed contract for the following test.

Let me explain this a little more detailed:

When I run $ truffle test with for example a transfer function from 0 tokens to 5 tokens. The next time I run the same test again the token balance of the account is 0 tokens again.

How can I run the test so that the state is updated after the previous test?

Example contract

pragma solidity ^0.4.4;

contract TestToken {

   mapping(address => uint256) balances;

   event Transfer(address indexed _from, address indexed _to, uint _value);

   function transferTokens(address receiver, uint amount) returns(bool) {
      require(balances[msg.sender] > amount);
      balances[msg.sender] -= amount;
      balances[receiver] += amount;
      Transfer(msg.sender, receiver, amount);
      return true;
   }

   function balanceOf(address owner) {
      return balances[owner];
   }

}

Example test

var TestToken = artifacts.require("./TestToken.sol");

contract('TestToken', function(accounts) {

   it("should transfer 5 tokens from accounts[0] to accounts[1]", function() {

      var token;

      return TestToken.deployed().then(function(instance) {
         token = instance;
         return token.transferTokens(accounts[1], 5, {from: accounts[0]});
      }).then(function() {
         return token.balanceOf(accounts[1]);
      }).then(function(balance) {
         assert.equal(balance.valueOf(), 5, "5 tokens not transfered");
      });
   })

});
1

Truffle makes a new deployment before each test, so each test will get fresh contracts. This is something desirable for reproducible tests.

One possible solution is to run all your tests inside the same 'contract' block. All of them will run with the same deployment

var TestToken = artifacts.require("./TestToken.sol");

contract('TestToken', function(accounts) {
  it('First test', async function() {
     const token = await TestToken.deployed();
  });
  it('Second test', async function() {
     const token = await TestToken.deployed();
  });
  // More tests follow
});

Another solution is to not use the test's deployed contracts but to deploy your own once at all the test use the same address.

var TestToken = artifacts.require("./TestToken.sol");

var testTokenAddress = '0x....'; // Existing address
function getTestToken() {
  return TestToken.at(testTokenAddress);
}

contract('TestToken 1', function(accounts) {
  it('A test', async function() {
     const token = await getTestToken();
  });
 });
contract('TestToken 2', function(accounts) {
  it('A test', async function() {
     const token = await getTestToken();
  });
 });

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.