Home > other >  Assert number of tests run by mocha.js
Assert number of tests run by mocha.js

Time:11-09

Is there a way to assert the number of tests that have been run by mocha?
E.g. something like:

afterAllTests(() => {
  expect(mocha.numTestsRun).to.be.greaterThan(400);
});

I recently upgraded from mocha 7.1.2 to 9.1.3 and the -R shorthand argument stopped working. My test suite went from running ~400 tests to only running ~10 top level tests. Switching back to --recursive fixed the issue, but I'd like to make sure something like this doesn't happen again.

My package.json looks something like this:

{
  "scripts": {
    "integrationTest": "mocha --recursive spec test/integration",
  }
}

CodePudding user response:

Rather than counting the number of tests that have been run so far, I would go with counting the number of tests that have been declared with Mocha. This ensures that the check for the total number of tests remains valid regardless of the order of execution.

To calculate the total number of tests, we need to count the number of tests declared in the top-level suite and in all of its sub-suites recursively (there is no shortcut AFAIK).

We start by declaring a new test (it can be placed anywhere) for the sole purpose of counting the total number of tests.

In this test, we can get the containing suite with this.runnable().parent. The suite in its turn has also a property parent that can be used to get the next higher containing suite, all the way up to the top-level suite (which is implicitly defined by Mocha). The top-level suite has a property root set to true.

Now, the top-level suite, like any other suite, has properties tests and suites that can be use to branch trough all descendant suites and count the total number of tests declared.

it('total number of tests should be > 400', function() { // Use `function()`, don't use `() =>`...

    let suite0 = this.runnable().parent; // ...because we need to access `this`.
    while (!suite0.root) suite0 = suite0.parent;
    // suite0 is now the top-level suite

    // Recursiveliy count the number of tests in each suite
    const countTests = (cnt, suite) => suite.suites.reduce(countTests, cnt   suite.tests.length);
    const totalTests = countTests(0, suite0);

    expect(totalTests).to.be.greaterThan(400);

});

This will count all tests, including those marked as skipped (but I suppose that's what you want).

Note also that - obviously - the test-counting-test itself only works as long as you don't forget to include it when you run Mocha. Moving the test logic to a top-level before or after hook will not change much, because those hooks have the same visibility as the tests declared in the same scope. You could put that test in a file that is just inside the spec folder, so it will be executed even without the --recursive flag. As a last resort, you could set the number of tests in an environment variable and check that value outside of Mocha.

  • Related