17

I have a test file in hardhat like so:

const { expect } = require("chai");

describe("contract tests", function () {
  it("does function one", async function () {
    expect(await someContract.someFunc()).to.equal(something);
  });
  it("does function two", async function () {
    expect(await someContract.someOtherFunction()).to.equal(somethingOtherThing);
  });
});

How can I test just one of the its at a time?

In mocha you can run a single test with the --grep command. Is there something similar for hardhat?

Something like:

npx hardhat test --grep "does function one"

or

npx hardhat test --grep "does function two"
2
  • 2
    Woah! The famous Patrick Collins is asking questions on Stack Overflow? I guess it's a good reminder that we're all always learning new things.
    – Tomiwa
    Jun 18 at 15:54
  • 2
    I try to always ask direct technical questions in forums if I can't find the answers right away. That way, they will get indexed by search engines so that next time myself and others can find the answers quickly. And pretending to know everything is disengenuous. Jun 29 at 21:27

5 Answers 5

17

Use .only(). For example, your test file would look like this:

const { expect } = require("chai");

describe.only("contract tests", function () {
  it("does function one", async function () {
    expect(await someContract.someFunc()).to.equal(something);
  });
  it("does function two", async function () {
    expect(await someContract.someOtherFunction()).to.equal(somethingOtherThing);
  });
});

and then you can run npx hardhat test and it will only run that test set.

If you just want one it, instead of using .only() on describe, you can use it.only().

EDIT:

As of hardhat version 2.9, you can use --grep as described in the original question.

7
  • 2
    This is great, but there is no command-line part I can run? I have to actually edit my code everytime I want to run just 1 test? Nov 10, 2021 at 19:19
  • 1
    @PatrickCollins yes, because that's the way Mocha works. I'm not sure you can change the test runner with Hardhat, but if you can, note that with Jest and Earl.js you can run specific tests from the command-line. Nov 10, 2021 at 19:44
  • 1
    Got it, thanks for the info all. Seems like this would be a nice improvement for mocha. Nov 10, 2021 at 21:34
  • 1
    You can use Mocha's --grep to filter tests by their description. I personally think that adding .only is just easier, but YMMV. Nov 11, 2021 at 15:02
  • 2
    Oh, and keep in mind that npx hardhat test doesn't support --grep (yet), so if you want to use it, you have to run mocha directly instead of using the test task. Nov 11, 2021 at 15:02
7

You'll be glad to know as of hardhat 2.9, the --grep parameter has been added to the test task! This adds the ability to pass in a regular expression through to mocha! This is cool because you can

  • Match a single part of the test. In your example Patrick, to run the first test:

    npx hardhat test --grep one

    would do the trick.

  • Even cooler is matching different tests. If you wanted to test all matches for tests involving add and convert, the command:

    npx hardhat test --grep "add|con?vert"

    would match all the below tests in our "mock" test suite.

describe('Mocha', function () {
  describe('"grep" option', function () {
    it('should add a RegExp to the mocha.options object', function () {});
    it('should convert string to a RegExp', function () {});
  });
  describe('"fgrep" option', function () {
    it('should escape and convert string to a RegExp', function () {});
  });
  describe('.grep()', function () {
    it('should add a RegExp to the mocha.options object', function () {});
    it('should convert grep string to a RegExp', function () {});
    it('should covert grep regex-like string to a RegExp', function () {});
  });
});

Why the ?? Well, it makes the n optional and I wanted to match one with a little typo.

0

I'm gonna post since this is not the best option. You can use https://www.npmjs.com/package/hardhat-watcher I then start it as a new package.json entry:

"watch-test": "hardhat watch test",

2
  • 1
    But you still need to use the .only yes? Dec 8, 2021 at 13:35
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Dec 8, 2021 at 20:39
0

If your tests are hardhat configuration specific, as specified in the CLI command, you could parse the CLI input directly in the test file. Then you could use Mocha's .skip() to ignore specific config based conditions.

I've applied this like the below example based off of network selections:

package.json

{
  ...,
  "scripts": {
    "test": "hardhat test --network localhost",
    "test-hardhat": "hardhat test --network hardhat",
    "test-net": "hardhat test --network rinkeby"
  },

sample-test.js

const { assert } = require('chai');

const PARMS = process.argv;
const NETWORK = PARMS[PARMS.indexOf('--network') + 1];

describe('ModifyVariable', function () {
    let contract;
    const inputStr = 'Applesauce';

    before(async () => {
        const ModifyVariable = await ethers.getContractFactory('ModifyVariable');
        contract = await ModifyVariable.deploy(10, inputStr);
        await contract.deployed();
    });

    // Maybe I'll run this. Maybe I won't...
    it('should change x to 1337', async function () {
        if (NETWORK === 'localhost') this.skip();

        await contract.modifyToLeet();
        const newX = await contract.x();
        assert.equal(newX.toNumber(), 1337);
    });

    // Always test rename to 'Bob'.
    it('should change publicString to "Bob"', async () => {
        await contract.modifyToBob();
        const newPublicString = await contract.publicString();
        assert.equal(newPublicString, 'Bob');
    });
});

describe('ModifyVariable', function () {
    let contract;
    const inputStr = 'Applesauce';

    // Maybe I'll run this. Maybe I won't...
    before(async function () {
        if (NETWORK === 'localhost') this.skip();

        const ModifyVariable = await ethers.getContractFactory('ModifyVariable');
        contract = await ModifyVariable.deploy(10, inputStr);
        await contract.deployed();
    });

    it(`should change publicString to "${inputStr}"`, async () => {
        await contract.modifyToInput(inputStr);
        const newPublicString = await contract.publicString();
        assert.equal(newPublicString, inputStr);
    })
});

output

$ npm run test

> hardhat-project1@1.0.0 test
> hardhat test --network localhost



  ModifyVariable
    - should change x to 1337
    √ should change publicString to "Bob" (2157ms)

  ModifyVariable
    - should change publicString to "Applesauce"


  1 passing (3s)
  2 pending
0

For anyone that finds this and is having a similar issue to me, .only or fit/fdescribe work great within a single file.

If you have multiple files you can do hardhat test ./test/testfile.js.

.only or fit won't work if you're running multiple test files at once.

1
  • when I run hardhat test ./test/testfile.js the output shows that it didn't find any tests in the file...
    – Jim
    Aug 4 at 17:00

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.