Description
openedon Jun 1, 2020
With the addition of root hook plugins and parallel mode, an important use case may have been omitted.
In serial mode, a root before all (before()
) hook can perform async setup (e.g., starting a test server) and a root after all (after()
) can perform async teardown (closing the server). This is not perfect, given Mocha could crash and the server would not get cleaned up, but I think it's behavior people expect.
In parallel mode, this behavior not available. Root hooks "before all" and "after all" run once per file. If you want to run something once and only once, you're kind of stuck.
One could abuse mochaHooks
by defining a Promise
-returning function, and doing setup there...
exports.mochaHooks = async () => {
// do something once only
});
... but there's no associated "teardown".
The only real workaround that I'm aware of is via script, e.g., {"scripts": {"test": "startServer && mocha; stopServer"}}
. Top-level await
suffers from the same problem as the above example--no associated teardown.
An idea for this would be to implement two new "hooks" in mochaHooks
, e.g., begin
and end
.
- These would be aggregated before
Mocha
begins running tests, similar to the behavior of the other hooks - The hooks are guaranteed (within reason) to run once and only once.
- These hooks can share a context with each other, but nothing else. You cannot access the current test context from
begin
, for instance. You could definethis.foo
inbegin
and access it inend
, I suppose. - Standard Node.js-style callbacks and
Promise
-returning functions allowed - They will always run in the main process
Alternatives:
- Instead of using
mochaHooks
, use a different property. - Instead of having a single property, use
mochaBegin
andmochaEnd
properties. - Name it something else, but be careful not to conflate it with existing hooks or interfaces (
setup
is going to be very confusing for those using thetdd
interface, for example).
cc @nicojs, who may have opinions about how this should work.