Skip to content
Merged
Prev Previous commit
Next Next commit
test_runner: cover non-randomized cancelled subtest report order
  • Loading branch information
pmarchini committed Mar 12, 2026
commit ae2950128cb9ab6a4b4f012c6e6996e31776a938
11 changes: 11 additions & 0 deletions test/fixtures/test-runner/cancelled-report-order.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import test from 'node:test';
import { setTimeout as sleep } from 'node:timers/promises';

test('parent', { timeout: 50, concurrency: 1 }, async (t) => {
t.test('first', async () => {
await sleep(1000);
});

t.test('second', async () => {});
t.test('third', async () => {});
});
27 changes: 27 additions & 0 deletions test/fixtures/test-runner/output/randomize_output_cli_none.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict';
require('../../../common');
const fixtures = require('../../../common/fixtures');
const spawn = require('node:child_process').spawn;

spawn(
process.execPath,
[
'--no-warnings',
'--test-reporter', 'spec',
'--test-concurrency', '1',
'--test-random-seed=12345',
'--test-isolation=none',
'--test',
fixtures.path('test-runner/shards/a.cjs'),
fixtures.path('test-runner/shards/b.cjs'),
fixtures.path('test-runner/shards/c.cjs'),
fixtures.path('test-runner/shards/d.cjs'),
fixtures.path('test-runner/shards/e.cjs'),
fixtures.path('test-runner/shards/f.cjs'),
fixtures.path('test-runner/shards/g.cjs'),
fixtures.path('test-runner/shards/h.cjs'),
fixtures.path('test-runner/shards/i.cjs'),
fixtures.path('test-runner/shards/j.cjs'),
],
{ stdio: 'inherit' },
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
✔ j.cjs this should pass (*ms)
✔ c.cjs this should pass (*ms)
✔ e.cjs this should pass (*ms)
✔ h.cjs this should pass (*ms)
✔ f.cjs this should pass (*ms)
✔ b.cjs this should pass (*ms)
✔ a.cjs this should pass (*ms)
✔ i.cjs this should pass (*ms)
✔ g.cjs this should pass (*ms)
✔ d.cjs this should pass (*ms)
ℹ Randomized test order seed: 12345
ℹ tests 10
ℹ suites 0
ℹ pass 10
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms *
22 changes: 22 additions & 0 deletions test/parallel/test-runner-run.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,28 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
for await (const _ of stream);
});

for (const isolation of ['process', 'none']) {
it(`should preserve cancelled queued subtest order without randomization (${isolation})`, async () => {
const stream = run({
files: [fixtures.path('test-runner', 'cancelled-report-order.mjs')],
isolation,
});
const cancelledNames = [];

stream.on('test:fail', ({ name, details }) => {
if (name === 'second' || name === 'third') {
cancelledNames.push(name);
assert.strictEqual(details.error.failureType, 'cancelledByParent');
}
});

// eslint-disable-next-line no-unused-vars
for await (const _ of stream);

assert.deepStrictEqual(cancelledNames, ['second', 'third']);
});
}

it('should be piped with dot', async () => {
const result = await run({
files: [join(testFixtures, 'default-behavior/test/random.cjs')]
Expand Down
11 changes: 11 additions & 0 deletions test/test-runner/test-output-randomize-output-cli-none.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Test that the output of test-runner/output/randomize_output_cli_none.js matches
// test-runner/output/randomize_output_cli_none.snapshot
import '../common/index.mjs';
import * as fixtures from '../common/fixtures.mjs';
import { spawnAndAssert, specTransform, ensureCwdIsProjectRoot } from '../common/assertSnapshot.js';

ensureCwdIsProjectRoot();
await spawnAndAssert(
fixtures.path('test-runner/output/randomize_output_cli_none.js'),
specTransform,
);