Testing with Web3.js & Truffle

Buidler allows you to use Truffle to test your smart contracts. This mainly means compatibility with the @truffle/contract package to interact with your smart contracts.

Truffle 4 and Truffle 5 are supported using the @nomiclabs/buidler-truffle4 and @nomiclabs/buidler-truffle5 plugins respectively. Both work with either Solidity 4 or 5.

Let's see how to do this using the Buidler sample project. Run these to start:

mkdir my-project
cd my-project
npm init --yes
npm install --save-dev @nomiclabs/buidler

Now run npx buidler inside your project folder and create a sample project. This is what the file structure should look like once you're done:

$ ls -l
total 296
drwxr-xr-x  378 fzeoli  staff   12096 Aug  7 16:12 node_modules/
drwxr-xr-x    3 fzeoli  staff      96 Aug  8 15:04 scripts/
drwxr-xr-x    3 fzeoli  staff      96 Aug  8 15:04 test/
drwxr-xr-x    3 fzeoli  staff      96 Aug  8 15:04 contracts/
-rw-r--r--    1 fzeoli  staff     195 Aug  8 15:04 buidler.config.js
-rw-r--r--    1 fzeoli  staff  139778 Aug  7 16:12 package-lock.json
-rw-r--r--    1 fzeoli  staff     294 Aug  7 16:12 package.json

Look at the buidler.config.js file and you'll see that the Truffle 5 plugin is enabled:

 













usePlugin("@nomiclabs/buidler-truffle5");

// This is a sample Buidler task. To learn how to create your own go to
// https://buidler.dev/guides/create-task.html
task("accounts", "Prints the list of accounts", async () => {
  const accounts = await web3.eth.getAccounts();

  for (const account of accounts) {
    console.log(account);
  }
});

module.exports = {};

Look at the file test/sample-test.js and you'll find these sample tests:

 


































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

// Traditional Truffle test
contract("Greeter", accounts => {
  it("Should return the new greeting once it's changed", async function() {
    const greeter = await Greeter.new("Hello, world!");
    assert.equal(await greeter.greet(), "Hello, world!");

    await greeter.setGreeting("Hola, mundo!");

    assert.equal(await greeter.greet(), "Hola, mundo!");
  });
});

// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha.
describe("Greeter contract", function() {
  let accounts;

  before(async function() {
    accounts = await web3.eth.getAccounts();
  });

  describe("Deployment", function() {
    it("Should deploy with the right greeting", async function() {
      const greeter = await Greeter.new("Hello, world!");
      assert.equal(await greeter.greet(), "Hello, world!");

      const greeter2 = await Greeter.new("Hola, mundo!");
      assert.equal(await greeter2.greet(), "Hola, mundo!");
    });
  });
});


As you can see in the highlighted line, the artifacts object is present in the global scope and you can use it to access the Truffle contract abstractions.

These examples show two approaches towards testing:

  • Using contract(), which is the traditional way to test with Truffle
  • Using describe(), which is the traditional way to test using Mocha

Truffle runs its tests with Mocha, but a few tools that integrate Mocha don't expect contract() and don't always work well. We recommend using the describe() approach.

You can run these tests by running npx buidler test:

$ npx buidler test
All contracts have already been compiled, skipping compilation.


Contract: Greeter
    ✓ Should return the new greeting once it's changed (265ms)

  Greeter contract
    Deployment
      ✓ Should deploy with the right greeting (114ms)


  2 passing (398ms)

If you want to use Truffle Migrations to initialize your tests and call deployed() on the contract abstractions, both @nomiclabs/buidler-truffle4 and @nomiclabs/buidler-truffle5 offer a fixtures feature to make this possible. Take a look at the Truffle migration guide to learn more.

Using Web3.js

To use Web3.js in your tests, an instance of it is available in the global scope. You can see this in the describe() test in sample-test.js:




















 















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

// Traditional Truffle test
contract("Greeter", accounts => {
  it("Should return the new greeting once it's changed", async function() {
    const greeter = await Greeter.new("Hello, world!");
    assert.equal(await greeter.greet(), "Hello, world!");

    await greeter.setGreeting("Hola, mundo!");

    assert.equal(await greeter.greet(), "Hola, mundo!");
  });
});

// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha.
describe("Greeter contract", function() {
  let accounts;

  before(async function() {
    accounts = await web3.eth.getAccounts();
  });

  describe("Deployment", function() {
    it("Should deploy with the right greeting", async function() {
      const greeter = await Greeter.new("Hello, world!");
      assert.equal(await greeter.greet(), "Hello, world!");

      const greeter2 = await Greeter.new("Hola, mundo!");
      assert.equal(await greeter2.greet(), "Hola, mundo!");
    });
  });
});


Checkout the plugin's README file for more information about it.

Last Updated: 10/2/2019, 1:48:02 PM