9

It seems that truffle test automatically invokes truffle deploy (aka truffle migrate).

As far as I'm concerned, these two functionalities are completely unrelated.

So I cannot quite figure out why Truffle works this way to begin with.

The docs do not seem to mention anything on this subject.

I would like to use truffle test for one thing and truffle deploy for another thing.

Is there any way to "tell" truffle test to avoid running truffle deploy?

Thank you!!!

  • In one of your comments below, you seem to suggest you've solved this - could you provide details as to how, please? – glowkeeper Sep 15 at 15:29
  • @glowkeeper: It's explained in that same comment. – goodvibration Sep 15 at 15:37
  • not really - any chance you could share some config'? – glowkeeper Sep 15 at 15:45
  • Aha - think I've worked this out! In deploy script: ``` if ( network === 'rinkeby' ) { return } ``` Then, in test script: ``` this.contract = await BlahContract.at('0x48B98faB029Cd2c77afA780Ab94c2d4e2f4879dA'); ``` Then run: truffle test --network rinkeby ``` – glowkeeper Sep 15 at 16:02
  • @glowkeeper: I added that as an answer (since it's too long to be posted as a comment). – goodvibration Sep 15 at 16:06
4

I ran into this issue as well, and it is indeed the intended behavior of truffle test: cleanroom behavior. Each run of truffle test redeploys the contracts. If it didn't, then saved state from a prior run could affect the results of a subsequent run, making your test suite non-deterministic.

But I wanted to preserve state between runs of truffle test. The suggested way to do this is documented as:

deployer.deploy(Contract, {overwrite: false})

Unfortunately, the above seems to fail in truffle 5.0.1 due to a parsing bug. So a workaround to force correct parsing is this:

deployer.deploy(Contract, {gas: 6720000, overwrite: false})

https://truffleframework.com/docs/truffle/testing/testing-your-contracts#clean-room-environment

Clean-room environment

Truffle provides a clean room environment when running your test files. When running your tests against Ganache or Truffle Develop, Truffle will use advanced snapshotting features to ensure your test files don't share state with each other. When running against other Ethereum clients like go-ethereum, Truffle will re-deploy all of your migrations at the beginning of every test file to ensure you have a fresh set of contracts to test against.

  • 1
    Nice answer, but it'd be even better if you linked to that parsing bug to see what's the status/workarounds/etc. – hmijail Jul 2 at 9:33
2

Before you can run any test, one has to define the starting point, the starting conditions in the smart contract. - Think about the values of the variable in the smart contracts. These conditions are defined by the deployment process. Hence, usually one would first run the deployment before testing. Also, this allows resetting the blockchain easily after each separate test.

If you do not want to do this, you might wanna try truffle scripts. They allow you to run any script or test.

  • Thank you. No, I would like to use truffle test because it provides a good report. I would like to create/deploy contracts myself - different contracts on each test. And most certainly not the same ones for every test. In some of my tests I use mockup contracts, with the purpose of testing a single contract in an isolated manner (aka unitest). In the migration script passed to truffle deploy, I would like to do "the real thing", since here my intention is not to test the contracts but to actually deploy them. – goodvibration May 28 '18 at 11:26
  • Then you might wanna use flags for the deployment: truffleframework.com/docs/advanced/configuration If no flag is passed, you simply do not execute any deployment code. Then truffle test runs through without deploying. If you hand over --network "testnetName" you could execute the deployment in the migration. – josojo May 28 '18 at 15:25
  • That's exactly how I ended up solving it, BTW (execute only if network == "production"). Thanks. – goodvibration May 28 '18 at 17:35
  • 1
    Though I wouldn't call them "flags", there are indeed 3 parameters passed to the script - deployer, network and accounts. – goodvibration May 28 '18 at 17:37
  • I have the same requirement - before I start developing frontend code for already deployed contracts, I wanna run some tests to make sure they work correctly! @josojo - can you share exactly how you would have 'without flags' working, please? – glowkeeper Sep 15 at 15:30
2

It is really embarrassing, how narrow minded the truffle authors think. My tests run their own deployment that is used in the tests. In my case, the truffle migration includes the steps that data is copied from the old instance to the new instance of the main contract, then the old contract is destroyed. Unfortunately, here the snapshot does not help, the old instance is not restored and a defect instance remains in the contract's json file. So I have to prevent the migration scripts from running. So there are good reasons, why migration should be optional and configurable in truffle test!

I solved it in the following way:

  • run a second canache-cli with a separete network named test
  • if the truffle migrate script is in network test, do nothing
  • run truffle test with option --network test

In detail:

Add on top of migrations/2_contract the line:

module.exports = async function(deployer, network, accounts) {
  if (network == "test") return; // test maintains own contracts
  …
}

Add new network test to truffle-config.js:

…
networks: {
  …
  development: {
    host: "127.0.0.1",
    port: 8545,
    network_id: "*"
  },
  test: {
    host: "127.0.0.1",
    port: 8546,
    network_id: "*"
  }
}
…

Run a second canache-cli (besides the one running network development:

In one console, I run ganache for development, for my GUI tests:

ganache-cli -d --db ${HOME}/tmp/ganache/development -i 123456 -p 8545

In another console, I run a separate ganache for test:

ganache-cli -d --db ${HOME}/tmp/ganache/test -i 654321 -p 8546

That's it! Now I can run:

truffle migrate --reset

And

truffle test --network test

Without interferences.

1

For those wondering on a solution, here's the one hinted at in the comments above:

First, truffle-config.js looks something like this:

module.exports = {
  networks: {
    rinkeby: {
      host: "localhost", // Connect to geth on the specified
      port: 8545,
      from: "0x8f03ca885434522d695735a28d6a8a93b4390da9", // default address to use for any transaction Truffle makes during migrations
      network_id: 4,
      gas: 4612388 // Gas limit used for deploys
    }
};

Then, in the 2_deploy... script:

if ( network === 'rinkeby' ) 
{ 
  return 
} 

Finally, in your test script:

this.contract = await BlahContract.at('0x48B98faB029Cd2c77afA780Ab94c2d4e2f4879dA') 

Then run: truffle test --network rinkeby

Obviously, you will need some Rinkeby ether and you will need to unlock an account, with something like personal.unlockAccount(eth.coinbase, "yourPassword", 3000); from the geth console, but I have this method working for me. Yay :)

0

The truffle test command-line uses the development network configuration.

In other words, it is in fact equivalent to truffle test network=development.

So I solved this problem by adding in each one of the migration scripts in my project:

module.exports = function(deployer, network, accounts) {
    // encapsulate everything with this `if` statement
    if (network == "production") {
        ...
    }
};

Thus, everything inside the if statement is not executed when running truffle test.

And in order to keep the option of deploying my contracts with Truffle, I added this in my Truffle configuration file (truffle.js or truffle-config.js):

    production: {
        host:       "localhost", // for example
        port:       7545,        // for example
        network_id: "*",         // for example
        gasPrice:   20000000000, // for example
        gas:        6721975      // for example
    }

Which allows me to deploy my contracts via either one of the following command lines:

  • truffle deploy --network=production
  • truffle migrate --network=production

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.