Description
Version
v20.6.1
Platform
Darwin Me-MacBook-Air.local 22.5.0 Darwin Kernel Version 22.5.0: Mon Apr 24 20:53:44 PDT 2023; root:xnu-8796.121.2~5/RELEASE_ARM64_T8103 arm64
Subsystem
node:test
What steps will reproduce the bug?
Given repo.js
:
import { test, before, after } from "node:test";
let promise;
let timeout_id;
before(() => {
promise = new Promise((resolve) => {
timeout_id = setTimeout(resolve, 2000);
});
});
after(() => {
clearTimeout(timeout_id);
});
await test("empty test", async () => {});
await test("500 ms test", async () => {
return new Promise((resolve) => setTimeout(resolve, 500));
});
Run node --test repo.js
How often does it reproduce? Is there a required condition?
Always reproduces.
What is the expected behavior? Why is that the expected behavior?
Expected the overall duration to be about 500ms.
What do you see instead?
The overall duration is about 2 seconds.
$ node --test repo.js
✔ empty test (1.217ms)
✔ 500 ms test (502.198333ms)
ℹ tests 2
ℹ suites 0
ℹ pass 2
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 2065.854416
Additional information
What is happening is test runner is waiting for the event loop to empty after all tests are run, then running after
.
This is a bug as usually in before
one would setup a background process/server and clean it up in after
. In this case the event loop will never be empty until after
is called.
The expected behaviour is for the test runner to wait for the event loop to empty after after
is called. In fact, it should wait until all concurrent tests have called their after
.