Time Travelling Truffle Tests

Andy Watt
edgefund
Published in
3 min readJul 22, 2018

Developing blockchain applications presents some very interesting and unique challenges, even for very experienced ‘traditional’ programmers. One aspect that I find tricky to wrap my head around is unit testing, and writing testable code. This is a real problem given how much more important it is for code to execute correctly on a blockchain. There’s no room for bugs, and so the testing is very important!

This post will address an issue that I have been working on recently, where a unit test was required to take an action, and then wait for a number of blocks to pass. I will explain how I achieved this using Truffle’s testing framework to artificially move their testing chain forward. I’ll supply helper functions in JavaScript that you can do this type of test by simply typing:

helper.advanceTimeAndBlock(secondsToAdvance)

Significant credit is due to Gareth for coming up with this solution!

The EdgeFund platform development is starting to take shape now. EdgeFund is a betting platform which requires a user to place a bet by issuing a transaction, and then waiting some blocks before checking back to see if their bet has won.

To test this functionality, the following steps need to happen:

  • A user sends a transaction that places a bet on block ‘n’.
  • The blockchain moves forward 5 blocks and ~60 seconds
  • The user checks if their bet is a winner and issues another transaction to claim their winnings on block ‘n+5’

This function is obviously not possible on the main network, or ever the public test nets, the the block creation and timestamping is done by the miners. However, it is possible when testing locally through two helper functions provided by the ganache-cli. These functions are:

evm_increaseTimeevm_mine

These functions are triggered by sending a transaction like this:

web3.currentProvider.send({
jsonrpc: "2.0",
method: "evm_increaseTime",
params: [600],
id: 123
})

Or:

web3.currentProvider.send({
jsonrpc: "2.0",
method: "evm_mine",
id: 123
})

There is one very important point to consider. When a block is mined, the timestamp of that block is printed into it and cannot be changed. The evm_increaseTime function does not change the time of the most recently mined block. It changes the time of the next block. In order to ‘see’ the new time, the next block has to be mined using the evm_mine function.

The following JavaScript wraps up these functions, making it really easy to write time travelling unit tests!

To make use of the above, add it into your truffle testing folder at helpers\truffleTestHelper.js The functions can be accessed in your test functions as per the example code below:

That’s it! Simple enough when you know how I guess, but this took us quite a bit of searching to piece together this solution. I hope that post pulls everything together for the next coder looking to do this!

I am currently working on EdgeFund, an open-source platform which offers a decentralised shared bankroll on the Blockchain. To learn more about EdgeFund, please visit our website or join our telegram group to chat to the team and be sure to follow us on Twitter!

--

--

Andy Watt
edgefund

Technical Lead and co-founder at Avalone Consultants. Angular, .NET, and blockchain developer.