Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚀 Feature: Global fixtures should run before any files are loaded #4508

Open
4 tasks done
lucasrcosta opened this issue Nov 12, 2020 · 10 comments · May be fixed by #4511
Open
4 tasks done

🚀 Feature: Global fixtures should run before any files are loaded #4508

lucasrcosta opened this issue Nov 12, 2020 · 10 comments · May be fixed by #4511
Labels
area: documentation anything involving docs or mochajs.org area: usability concerning user experience or interface semver-major implementation requires increase of "major" version number; "breaking changes" status: accepting prs Mocha can use your help with this one!

Comments

@lucasrcosta
Copy link

lucasrcosta commented Nov 12, 2020

Prerequisites

  • Checked that your issue hasn't already been filed by cross-referencing issues with the faq label
  • 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.
  • '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
  • 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
@boneskull
Copy link
Contributor

boneskull commented Nov 13, 2020

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 boneskull added area: documentation anything involving docs or mochajs.org status: waiting for author waiting on response from OP - more information needed area: usability concerning user experience or interface and removed unconfirmed-bug labels Nov 13, 2020
@boneskull boneskull changed the title Global fixtures loading tests before mochaGlobalSetup global fixtures should run before any files are loaded Nov 13, 2020
boneskull added a commit that referenced this issue Nov 13, 2020
BREAKING CHANGE

`Mocha#run()` was orchestrating if and when to run global setup/teardown fixtures, but `Mocha#run()` must be called after test files have been loaded.  This is a problem, because:

1. `--delay` may expect something created in a fixture to be accessible, but it won't be
2. Any future support for async suites is similarly negatively impacted
3. It was inconsistent between "watch" and "single run" mode; "watch" mode already has this behavior!

This change causes setup fixtures to run _before_ any test files have been loaded.  In Node.js, this happens in `lib/cli/run-helpers`.

- Added two functions to `Mocha`; `Mocha#globalSetupEnabled()` and `Mocha#globalTeardownEnabled()` which both return booleans
- Correct order of operations is asserted in `test/integration/global-fixtures.spec.js`
- Removed low-value (and newly broken) unit tests where `Mocha#run` called `runGlobalSetup`/`runGlobalTeardown`
- Add a note to `browser-entry.js` about global fixtures

This is breaking because:

1. Browser users now must run setup/teardown fixtures manually.
2. Somebody's test harness might expect test files to be loaded (and suites run) _before_ global setup fixtures execute.
@boneskull
Copy link
Contributor

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 boneskull added the semver-major implementation requires increase of "major" version number; "breaking changes" label Nov 13, 2020
@lucasrcosta
Copy link
Author

lucasrcosta commented Nov 13, 2020

@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.

@SgtPooki
Copy link

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?

@witrin
Copy link

witrin commented Nov 1, 2021

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
Copy link

witrin commented Dec 17, 2021

@boneskull How is the planing about this?

@mariobm
Copy link

mariobm commented Apr 26, 2022

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

@justinasfour04
Copy link

justinasfour04 commented Jul 27, 2022

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

@justinasfour04
Copy link

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

@codembark
Copy link

codembark commented Dec 10, 2023

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!

@JoshuaKGoldberg JoshuaKGoldberg added status: accepting prs Mocha can use your help with this one! and removed status: waiting for author waiting on response from OP - more information needed labels Dec 28, 2023
@JoshuaKGoldberg JoshuaKGoldberg changed the title global fixtures should run before any files are loaded 🚀 Feature: global fixtures should run before any files are loaded Dec 28, 2023
@JoshuaKGoldberg JoshuaKGoldberg changed the title 🚀 Feature: global fixtures should run before any files are loaded 🚀 Feature: Global fixtures should run before any files are loaded Dec 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: documentation anything involving docs or mochajs.org area: usability concerning user experience or interface semver-major implementation requires increase of "major" version number; "breaking changes" status: accepting prs Mocha can use your help with this one!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants