I am currently testing a contract that can evolve in different ways, depending on the interaction between parties. But all these possible scenarios share the same initialization.

So, the question I have is the following. When I am writing a test for this contract in Truffle/Ganache, is it possible to run a single chain until the decision point, then create several copies of the test blockchain state, one for each possible scenario?

I know that Ganache offers the evm_snapshot and evm_revert RPC calls. But it is not clear to me how to use them and how it interacts with Truffle and Mocha.

Also, can I use nested contract directives, as we can nest describe in Mocha?

Ideally I would like to do something like this:

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

contract('Contract', function(accounts) {
  beforeEach(async function() {
    // launch contract
    let contract = await Contract
        .new({ from: accounts[2], gas: 2000000 });

    // let users interact here
    // ...

  contract('Agreement', function(accounts) {
    it('Payment is processed', async function() {
      // test that payment was processed

  contract('Disagreement, see who is right', function(accounts) {

    contract('Alice right', function(accounts) {
      it('Punish Bob', async function() {
        // show that Alice is right and punish Bob
    contract('Alice right', function(accounts) {
      it('Punish Alice', async function() {
        // show that Bob is right and punish Alice

You see that we are testing three different outcomes, but they share the same initialization. I would like to avoid starting three fresh chains, one for each test. Is it possible and how one does it?

1 Answer 1


After testing here, I realized that the above code works in the following sense. Truffle will automatically snapshot and revert the two tests above. Some important observations:

  • One should not nest the directive contracts inside one another in this case, since there is only one contract being tested. We should instead use describes inside contract.
  • Using before does not work properly with snapshots. One should instead use beforeEach as stated in the question.
  • In the code above I forgot the keyword async in some function declarations. It should be present in each describe and it directive.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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