简体   繁体   中英

Mocha.run() exits without awaiting async tests

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.

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);
  }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM