Reputation: 21
I want to use mocha
to run some basic post-deploy tests against live services. I want to programmatically load tests based upon a config object passed to the test script.
The problem I'm encountering is that mocha.run()
executes and exits the node
process without continuing with the rest of the code. It is not clear to me how to force node
to wait for the mocha
result and continue with the rest of the code.
mocha-setup.js
const Mocha = require('mocha');
const util = require('util');
const { Test, Suite } = Mocha;
const timeoutMillis = 300000; // five minutes
const mocha = new Mocha({
timeout: timeoutMillis,
reporter: 'mochawesome',
reporterOptions: {
reportDir: '../reports/unit'
},
color: true,
});
const makeSuite = (suiteName) => Suite.create(mocha.suite, suiteName);
const runMochaTests = async (tests, config) => {
const suite = makeSuite('My programmatic test suite');
tests.forEach(({ test, statement }) => {
suite.addTest(new Test(statement, async () => {
await test(config);
}));
});
console.log('This logs as expected.');
const promisifyMocha = util.promisify(() => mocha.run());
const result = await promisifyMocha(); // code seems to exit here
console.log('I am never logged');
console.log(result); // also never logged
// `result` is never returned, and higher level code implementing `runMochaTests` does not continue either
return result; // Eventually, I want to return the number of failures
};
module.exports = {
runMochaTests,
};
The plan is for runMochaTests
to return the number of failures. runMochaTests()
will be used by different higher order code modules as necessary.
Lastly, in my best life, I would not have to manually promisify mocha at all. If there was a way to use something like const result = await mocha.run()
, that feels like the best implementation.
Upvotes: 1
Views: 313
Reputation: 21
My problem was that Mocha
is fundamentally about event listeners, not promises. Using this reference code, I ended up with...
const runMochaTests = async (tests, config) => new Promise((resolve, reject) => {
const testResults = [];
let numberOfFailures = 0;
try {
const suite = makeSuite('Verify Regional Apps');
tests.forEach(({ test, statement }) => {
suite.addTest(new Test(statement, async () => {
await test(config);
}));
});
const runner = mocha.run();
runner.on('test end', (testResult) => {
if (testResult.state === 'failed') numberOfFailures += 1;
testResults.push(testResult);
});
runner.on('end', () => {
runner.removeAllListeners('test end');
runner.removeAllListeners('end');
ClearModule.all(); // Needed to ensure all tests are executed every execution.
resolve(numberOfFailures);
});
} catch (err) {
reject(err);
}
});
Upvotes: 1