[Ethereum] Truffle test doesn’t connect to Ganache

connectionsganacheNetworktruffletruffle-test

I'm using Truffle and Ganache for my development environment. Using the truffle console or truffle external scripts everything works fine, but truffle test does not seem to be connected to Ganache:

When performing truffle exec ./script.js --network ganache everything works as expected. It shows the right contract address (as visible in Ganache UI) and in Ganache I can see the transactions having been performed on the contract.

Using network 'ganache'.

Test contract fetched 0xee09Bb5C1B6703f03db3263de408200ee134324D
BN { negative: 0, words: [ 0, <1 empty item> ], length: 1, red: null }
BN { negative: 0, words: [ 11, <1 empty item> ], length: 1, red: null }

But when performing truffle test --network ganache a different contract address is shown which I can't finde in Ganache UI and no transactions are visible in Ganache. However, the transactions seem to have been executed somewhere, but apparently not in Ganache.

Using network 'ganache'.

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.

  Contract: 1st Test
Test contract fetched 0xD8F3b0A6B0Db4325ea309C7ac8e5CE17AB22D322
BN { negative: 0, words: [ 0, <1 empty item> ], length: 1, red: null }
BN { negative: 0, words: [ 11, <1 empty item> ], length: 1, red: null }
    ✓ should have set correct id (173ms)

Any idea why truffle testdoes not connect to Ganache?

Below my configuration:

Versions

Truffle v5.3.0 (core: 5.3.0)
Solidity - 0.8.3 (solc-js)
Node v15.13.0
Web3.js v1.2.9

truffle-config.js

networks: {
  ganache: {
    host: "127.0.0.1",
    port: 7545,
    network_id: "*",
  }
}

Contract Test.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract Test {

    uint public id = 0;
   
    function setId(uint _id) public {
        id = _id;
    }

    function getId() public view returns (uint) {
        return id;
    }

}

script.js

module.exports = async function(callback) {
    const Test = artifacts.require("Test");
    try {      
        // Init
        const instance = await Test.deployed();
        console.log('Test contract fetched', instance.address);

        // Get ID
        var id = await instance.getId();
        console.log(id);

        // Set ID
        await instance.setId(11);

        // Get ID
        id = await instance.getId();
        console.log(id);   
    } catch (error) {
        console.error(error);
    }
    callback();
}

test.js

const Test = artifacts.require("Test");

contract("1st Test", async accounts => {
 
    it ("should have set correct id", async ()=> {
        const instance = await Test.deployed();
        console.log('Test contract fetched', instance.address);

        var id = await instance.getId();
        console.log(id);

        await instance.setId(11);

        var id = await instance.getId();
        console.log(id);

        assert.equal(id, 11);
    });

});

Best Answer

Meanwhile I figured out the issue thanks to this blog post: https://forum.openzeppelin.com/t/truffle-tests-not-being-run-against-contract-deployed-to-ganache-instead-uses-another-contract-address/4402/15

Summary

  • Truffle test always deploys a new contract to ensure tests run on a clean contract (however I couldn't make it visible in Ganache UI)
  • Adding overwrite: false as argument to the deploy function in the migrations script seems to do the trick
  • However, in the version I used only adding the overwrite argument doesn't work, only when adding also another argument like "from"

Using the following deploy script worked for me to connect truffle test with an existing contract visible in Ganache UI:

 module.exports = async function (deployer) {
   const accounts = await web3.eth.getAccounts();
   await deployer.deploy(Test, {from: accounts[0], overwrite: false});
   this.deployedTest = await Test.deployed();
   console.log(`Migrations deployed Test Contract: ${this.deployedTest.address}`);
};
Related Topic