docs/src/content/docs/features/parallel-mode.mdx
:::note[New in v8.0.0] :::
Depending on the number and nature of your tests, you may find a significant performance benefit when running tests in parallel (using the --parallel flag).
Parallel tests should work out-of-the box for many use cases. However, you must be aware of some important implications of the behavior.
:::note Authors of third-party libraries built on Mocha should read this! :::
Due to the nature of the following reporters, they cannot work when running tests in parallel:
These reporters expect Mocha to know how many tests it plans to run before execution. This information is unavailable in parallel mode, as test files are loaded only when they are about to be run.
In serial mode, tests results will "stream" as they occur. In parallel mode, reporter output is buffered; reporting will occur after each file is completed. In practice, the reporter output will appear in "chunks" (but will otherwise be identical). If a test file is particularly slow, there may be a significant pause while it's running.
You cannot use it.only, describe.only, this.only(), etc., in parallel mode.
This is for the same reason as the incompatible reporters noted above: in parallel mode, Mocha does not load all files and suites into memory before running tests.
Suggested workarounds:
--grep or --fgrep instead; it's not particularly efficient, but it will work.:::tip
If parallel mode is defined in your config file, you can temporarily disable it on the command-line by using either the --no-parallel flag or reducing the job count, e.g., --jobs=0.
:::
In parallel mode, Mocha does not guarantee the order in which test files will run, nor which worker process runs them.
Because of this, the following options, which depend on order, cannot be used in parallel mode:
Running tests in parallel mode will naturally use more system resources. The OS may take extra time to schedule and complete some operations, depending on system load. For this reason, the timeouts of individual tests may need to be increased either globally or otherwise.
When used with --bail (or this.bail()) to exit after the first failure, it's likely other tests will be running at the same time.
Mocha must shut down its worker processes before exiting.
Likewise, subprocesses may throw uncaught exceptions.
When used with --allow-uncaught, Mocha will "bubble" this exception to the main process, but still must shut down its processes.
Either way, Mocha will abort the test run "very soon."
:::note This only applies when running in parallel mode. :::
A root hook is a hook in a test file which is not defined within a suite.
An example using the bdd interface:
// test/setup.js
// root hook to run before every test (even in other files)
beforeEach(function () {
doMySetup();
});
// root hook to run after every test (even in other files)
afterEach(function () {
doMyTeardown();
});
When run (in the default "serial" mode) via this command:
mocha --file "./test/setup.js" "./test/**/*.spec.js"
setup.js will be executed first, and install the two hooks shown above for every test found in ./test/**/*.spec.js.
The above example does not work in parallel mode.
When Mocha runs in parallel mode, test files do not share the same process, nor do they share the same instance of Mocha. Consequently, a hypothetical root hook defined in test file A will not be present in test file B.
Here are a couple suggested workarounds:
require('./setup.js') or import './setup.js' at the top of every test file.
Best avoided for those averse to boilerplate.If you need to run some code once and only once, use a global fixture instead.
Parallel mode is only available in Node.js, for now.
Third-party reporters may encounter issues when attempting to access non-existent properties within Test, Suite, and Hook objects.
If a third-party reporter does not work in parallel mode (but otherwise works in serial mode), please file an issue.
If you find your tests don't work properly when run with --parallel, either shrug and move on, or use this handy-dandy checklist to get things working:
--timeout)Some types of tests are not so well-suited to run in parallel. For example, extremely timing-sensitive tests, or tests which make I/O requests to a limited pool of resources (such as opening ports, or automating browser windows, hitting a test DB, or remote server, etc.).
Free-tier cloud CI services may not provide a suitable multi-core container or VM for their build agents.
Regarding expected performance gains in CI: your mileage may vary.
It may help to use a conditional in a .mocharc.js to check for process.env.CI, and adjust the job count as appropriate.
It's unlikely (but not impossible) to see a performance gain from a job count greater than the number of available CPU cores. That said, play around with the job count--there's no one-size-fits all, and the unique characteristics of your tests will determine the optimal number of jobs; it may even be that fewer is faster!
:::note[New in v9.2.0] :::
Each process launched by parallel mode is assigned a unique id, from 0 for the first process to be launched, to N-1 for the Nth process.
This worker id may be accessed in tests via the environment variable MOCHA_WORKER_ID.
It can be used for example to assign a different database, service port, etc for each test process.