mocha icon indicating copy to clipboard operation
mocha copied to clipboard

global fixtures should run before any files are loaded

Open lucasrcosta opened this issue 3 years ago • 9 comments

Prerequisites

  • [x] Checked that your issue hasn't already been filed by cross-referencing issues with the faq label
  • [x] Checked next-gen ES issues and syntax problems by using the same environment and/or transpiler configuration without Mocha to ensure it isn't just a feature that actually isn't supported in the environment in question or a bug in your code.
  • [x] 'Smoke tested' the code to be tested by running it outside the real test suite to get a better sense of whether the problem is in the code under test, your usage of Mocha, or Mocha itself
  • [x] Ensured that there is no discrepancy between the locally and globally installed versions of Mocha. You can find them with: node node_modules/.bin/mocha --version(Local) and mocha --version(Global). We recommend that you not install Mocha globally.

Description

When using global fixtures, mocha loads the test files before running mochaGlobalSetup. This can cause issues when dependencies themselves load top-level configurations . But when --watch is passed, it works as expected.

This behavior differs from the following statements in the documentation:

Work identically parallel mode, watch mode, and serial mode Now, before Mocha loads and runs your tests, it will execute the above global setup fixture, starting a server for testing.

Steps to Reproduce

fixtures.js

exports.mochaGlobalSetup = function() {
  console.log(`mochaGlobalSetup`);
}

test.js

console.log('Test file loaded')

it('runs', () => { })

Expected behavior: Should run mochaGlobalSetup before loading the test files in all cases.

Actual behavior: [What actually happens]

> npx mocha -r fixtures.js test.js
Test file loaded
mochaGlobalSetup

  ✓ runs

  1 passing (3ms)
> npx mocha -r fixtures.js test.js --watch
mochaGlobalSetup
Test file loaded

  ✓ runs

  1 passing (2ms)

ℹ [mocha] waiting for changes...

Reproduces how often: 100%

Versions

  • node --version: Unknown command: mocha
  • node node_modules/.bin/mocha --version: 8.2.1
  • node --version: v10.22.1
  • Your operating system: macOS Catalina 10.15.7 64bit
  • Your shell (e.g., bash, zsh, PowerShell, cmd): fish

lucasrcosta avatar Nov 12 '20 23:11 lucasrcosta

This is intended behavior, but

  1. the documentation is correct in that the fixtures are run before your tests
  2. it is incorrect in that the fixtures are not run before your test files load

the reason it is the way it is: it'd otherwise be unusable in a browser without adding more API surface, and we try to keep things the same between node/browser as much as possible.

this will be a problem if we allow async suites, since the suites would potentially try to use a resource (e.g. connect to a port) that a global setup fixture created... hm.

two questions:

  1. does this behavior prevent you from using global fixtures?
  2. if you used it as it works now, and we changed global setup fixtures to run before the test files are loaded, would that break what you're doing?

boneskull avatar Nov 13 '20 19:11 boneskull

I've created #4511 to address this. I agree that the behavior should change. Hopefully there hasn't been too much adoption of the feature yet..

boneskull avatar Nov 13 '20 21:11 boneskull

@boneskull thank you for addressing this.

  1. does this behavior prevent you from using global fixtures?

It does, since the test files are loaded before the fixtures. I'm working in a codebase that loads configurations from a database before importing the files to start a webserver. Some of it's dependencies use these configurations on top-level code (regardless of wether that's good practice or not), so today I cannot push global fixtures to the code since it would break the CI workflow.

  1. if you used it as it works now, and we changed global setup fixtures to run before the test files are loaded, would that break what you're doing?

No, in fact the behavior on watch mode is exactly that, so I've been developing that way the last few days. I understand I'll have to revert the introduction of global fixtures and wait for this to be finished in order to adopt it.

By the way, this is a great feature and it makes the test setup process so much clearer. Specially if you can delay the files being loaded, so that all code can be in the proper place. Congratulations.

lucasrcosta avatar Nov 13 '20 23:11 lucasrcosta

I left a comment saying the setup and teardown functions weren't being called for me, they are.. I was doing


exports = {
    mochaGlobalSetup,
    mochaGlobalTeardown,
    mochaHooks,
};

instead of



exports.mochaGlobalSetup = mochaGlobalSetup;
exports.mochaGlobalTeardown = mochaGlobalTeardown;
exports.mochaHooks = mochaHooks;

too used to typescript ¯_(ツ)_/¯. Hopefully leaving this comment helps someone else?

SgtPooki avatar Nov 25 '20 23:11 SgtPooki

Without this patch we were currently not able to perform integration tests for one of our bigger systems in a clean and lean way. We really hope for a merge here. Because 9 is already released.

witrin avatar Nov 01 '21 12:11 witrin

@boneskull How is the planing about this?

witrin avatar Dec 17 '21 21:12 witrin

This feature would be a game-changer for me. It's really needed.

mariobm avatar Apr 26 '22 11:04 mariobm

what is the status on this? I need this fix in version 8.2.0

justinasfour04 avatar Jul 27 '22 15:07 justinasfour04

This issue is 2 years old, does anyone have a work-around?

justinasfour04 avatar Jul 29 '22 18:07 justinasfour04

This prevents me from using global fixtures to set up integration tests. My use case is starting a database before importing a server module in the test file which requires the database to exist. I'll have to find another work around in the meantime.

Appreciate all the hard work you folks put into Mocha!

codembark avatar Dec 10 '23 00:12 codembark