trufflesuite / truffle-core

Core code for Truffle command line tool
MIT License
93 stars 93 forks source link

In opposed to what's specified in the docs, 'truffle test' invokes 'truffle deploy' #143

Open barakman opened 6 years ago

barakman commented 6 years ago

Issue

When executing truffle test, it immediately invokes truffle deploy.

It is not really clear why truffle test is to be preceded by truffle deploy, since these two functionalities are essentially designated for two different goals.

Moreover, for Ganache users, it appears to be in contrast with the specification in the docs, which state:

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.

The implementation of this can be found in file /node_modules/truffle/build/cli.bundled.js:

var Test = {
  run: function(options, callback) {
    ...
    this.getAccounts(web3).then(function(accs) {
      ...
    }).then(function(paths) {
      ...
      return self.performInitialDeploy(config, test_resolver);
    }).then(function() {
      ...
      return self.defineSolidityTests(mocha, testContracts, dependency_paths, runner);
    }).then(function() {
      ...
      return self.setJSTestGlobals(web3, accounts, test_resolver, runner);
    }).then(function() {
      ...
    }).catch(callback);
  },
  ...
  performInitialDeploy: function(config, resolver) {
    return new Promise(function(accept, reject) {
      Migrate.run(config.with({
        reset: true,
        resolver: resolver,
        quiet: true
      }), function(err) {
        if (err) return reject(err);
        accept();
      });
    });
  },
  ...
  setJSTestGlobals: function(web3, accounts, test_resolver, runner) {
    return new Promise(function(accept, reject) {
      ...
      var template = function(tests) {
        this.timeout(runner.TEST_TIMEOUT);

        before("prepare suite", function(done) {
          this.timeout(runner.BEFORE_TIMEOUT);
          runner.initialize(done);
        });

        beforeEach("before test", function(done) {
          runner.startTest(this, done);
        });

        afterEach("after test", function(done) {
          runner.endTest(this, done);
        });

        tests(accounts);
      }
      ...
    });
  }
};

As you can see, function run first calls performInitialDeploy and then calls setJSTestGlobals, which ultimately invokes tests(accounts).

Environment