Limits of Global Hooks in Mocha's Parallel Test Execution
0 reputation · 29 Oct 2022, 20:51 UTC
0 reputation · 29 Oct 2022, 20:51 UTC
Mocha 8.0.0 introduced the --parallel flag, which runs each test file in a separate worker process. This isolation removes shared global state between files and makes execution order nondeterministic. However, the framework does not explicitly document how global lifecycle hooks (before, after, beforeEach, afterEach) behave in this mode.
While each worker processes its own test files, it is unclear whether global hooks execute once per worker or once per file. This ambiguity can lead to inconsistent setup and teardown, especially when hooks modify shared resources or rely on order.
before hooks run once per worker or per test file?33275 reputation · 30 Oct 2022, 05:07 UTC
In Mocha's parallel mode (--parallel), global before and after hooks execute once per worker process, not once per test suite or once per file. Because Mocha spawns separate worker processes to isolate test files, any hook defined in a root-level setup file is re-executed every time a new worker is initialized to handle a batch of tests.
Because each worker is a distinct Node.js process, the following behaviors apply:
before hook (e.g., a global JavaScript object or variable) is local to that specific worker. Tests running in Worker A cannot access data initialized by Worker B.To handle setup and teardown across parallel workers without creating race conditions or redundant overhead, move shared logic outside of Mocha's internal hook system:
--require or a custom wrapper script to execute a one-time setup before the Mocha process spawns its workers.UPSERT or IF NOT EXISTS logic to prevent collisions.You can verify this behavior by logging the process ID within a root-level hook. If you see multiple unique PIDs in your console output, the hook is running per worker:
before(() => {
console.log(`Worker PID: ${process.pid}`);
});
Diagnostic Note: To provide a more specific architectural recommendation, please clarify if your hooks are modifying in-memory JavaScript state or interacting with an external resource (e.g., a SQL database or API).
Use comments to ask for clarification. Post a solution as an answer.
33,275 reputation · 30 Oct 2022, 04:42 UTC
When --parallel is enabled, Mocha spawns one worker per test file. A global before or after hook defined in a root‑level file is evaluated once inside each worker, effectively once per file.
Because each worker has its own process memory, state set up in a global hook is isolated to that worker. If you need a truly one‑time setup (e.g., seeding a database), use --require or an external script that runs before workers are spawned.