mocha: Mocha can't run tests twice programmatically

Programmatically, I cannot run a Mocha test twice.

I.e. I can’t do mocha.run() twice.

I looked at a similar issue (#995), however, the solutions are not optimal and/or not work.

For example, deleting the require cache is not a solution for me, as I need to use the require cache.

Is there a way to mocha.run() twice?

Thanks in advance!

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 7
  • Comments: 42 (19 by maintainers)

Commits related to this issue

Most upvoted comments

I ran into the same problem. Why was this issue closed? Making a new instance of Mocha, and adding files should behave deterministically without modifying the require cache. Seems like a bug.

I had the same problem.

Reading the similar issue #736, it seems it’s all about cleaning the “require.cache” of the previously loaded spec’s file

Here my current solution:

launchTests(){
  let _sTestDir = 'tests/specs';
  let _oMocha = new Mocha();
  fs.readdirSync( _sTestDir ).filter( function( oFile ){
    return ( oFile.substr( -3 ) === '.js' );
  }).forEach(function( sFile ){
    let _sPathSpec = path.join( path.resolve(), _sTestDir, sFile );
    // Resetting caches to be able to launch tests multiple times...
   delete require.cache[ _sPathSpec ];
   // Adding test
    _oMocha.addFile( _sPathSpec );
  });
  _oMocha.run();
}

Ok, I’ve investigated the issues a bit and I want to propose the following changes. They are designed to be 100% backward compatible and minor while still allowing for the new feature. @boneskull @plroebuck do you agree with these changes? I’d be willing to prepare the PR.

🔀 cleanReferences

I want to add a feature to allow references not to be cleared. Let’s call it autoDispose. By default it would be true (non-breaking change). But if you use mocha programmatically you are allowed to set it to false, you would have to call dispose on the mocha instance later if you still want to dispose.

🔢 “bits of state”

For the bits of state issue, I’m pretty sure that the state is situated in Suite, Test and Runnable. I would like to add a reset method in each, which resets the state. It would be called from the Mocha class, whenever an nth test run is started (where n > 1).

This way the way of working within mocha remains mostly the same. No big changes needed in the respective classes, responsibility, etc.

🏡 Housekeeping

I would also want to add 2 new validations:

  1. Whenever mocha’s run method is called an “object is already disposed” error will be thrown whenever the mocha’s instance is already disposed (either by autoDispose, or by a manual dispose).
  2. Whenever mocha’s run method is called while a run is already in progress a “mocha run is already in progress” error is thrown.

sounds reasonable to me. you’ll also want to ensure there’s no eventemitter leaks happening.

@nicojs Thanks - that’s what I should have done.

You can call it on the mocha object itself, using the programmatic interface: https://mochajs.org/api/mocha

@RossVertizan are you building a mutation testing framework by any chance? 😉

I just don’t think our maintainer team has the resources to embark on such a …quest.

Haha

Thanks for the clear responses. If I find a couple of hours in the coming weeks, I might take a look. One might say, I will embark on a quest 🏇