31

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"
Patrick Collins
  • 11,186
  • 5
  • 44
  • 97
  • 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 '22 at 15:54
  • 4
    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. – Patrick Collins Jun 29 '22 at 21:27

5 Answers5

26

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.

Patrick Collins
  • 11,186
  • 5
  • 44
  • 97
Julissa DC
  • 1,888
  • 1
  • 8
  • 21
13

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.

Namaskar
  • 239
  • 2
  • 3
3

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.

Ping
  • 31
  • 2
  • when I run hardhat test ./test/testfile.js the output shows that it didn't find any tests in the file... – Jim Aug 04 '22 at 17:00
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",

Elyx0
  • 101
  • 1
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