test_runner: add `testId` to test events · nodejs/node@f68189b · GitHub
Skip to content

Commit f68189b

Browse files
MoLowaduh95
authored andcommitted
test_runner: add testId to test events
Signed-off-by: Moshe Atlow <moshe@atlow.co.il> PR-URL: #62772 Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
1 parent 5c27704 commit f68189b

5 files changed

Lines changed: 146 additions & 13 deletions

File tree

doc/api/test.md

Lines changed: 18 additions & 0 deletions

lib/internal/test_runner/test.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,8 @@ class Test extends AsyncResource {
590590
this.timeout = kDefaultTimeout;
591591
this.entryFile = entryFile;
592592
this.testDisambiguator = new SafeMap();
593+
this.nextTestId = 1;
594+
this.testId = 0;
593595
} else {
594596
const nesting = parent.parent === null ? parent.nesting :
595597
parent.nesting + 1;
@@ -606,6 +608,7 @@ class Test extends AsyncResource {
606608
this.childNumber = parent.subtests.length + 1;
607609
this.timeout = parent.timeout;
608610
this.entryFile = parent.entryFile;
611+
this.testId = this.root.nextTestId++;
609612

610613
if (isFilteringByName) {
611614
this.filteredByName = this.willBeFilteredByName();
@@ -890,7 +893,7 @@ class Test extends AsyncResource {
890893
const deferred = this.dequeuePendingSubtest();
891894
const test = deferred.test;
892895
this.assignReportOrder(test);
893-
test.reporter.dequeue(test.nesting, test.loc, test.name, this.reportedType);
896+
test.reporter.dequeue(test.nesting, test.loc, test.name, this.reportedType, test.testId);
894897
await test.run();
895898
deferred.resolve();
896899
}
@@ -1147,7 +1150,7 @@ class Test extends AsyncResource {
11471150
// it. Otherwise, return a Promise to the caller and mark the test as
11481151
// pending for later execution.
11491152
this.parent.unfinishedSubtests.add(this);
1150-
this.reporter.enqueue(this.nesting, this.loc, this.name, this.reportedType);
1153+
this.reporter.enqueue(this.nesting, this.loc, this.name, this.reportedType, this.testId);
11511154
if (this.root.harness.buildPromise || !this.parent.hasConcurrency()) {
11521155
const deferred = PromiseWithResolvers();
11531156

@@ -1170,7 +1173,7 @@ class Test extends AsyncResource {
11701173
}
11711174

11721175
this.parent.assignReportOrder(this);
1173-
this.reporter.dequeue(this.nesting, this.loc, this.name, this.reportedType);
1176+
this.reporter.dequeue(this.nesting, this.loc, this.name, this.reportedType, this.testId);
11741177
return this.run();
11751178
}
11761179

@@ -1432,7 +1435,10 @@ class Test extends AsyncResource {
14321435
const report = this.getReportDetails();
14331436
report.details.passed = this.passed;
14341437
this.testNumber ||= ++this.parent.outputSubtestCount;
1435-
this.reporter.complete(this.nesting, this.loc, this.testNumber, this.name, report.details, report.directive);
1438+
this.reporter.complete(
1439+
this.nesting, this.loc, this.testNumber, this.name,
1440+
report.details, report.directive, this.testId,
1441+
);
14361442
this.parent.activeSubtests--;
14371443
}
14381444

@@ -1585,9 +1591,15 @@ class Test extends AsyncResource {
15851591
const report = this.getReportDetails();
15861592

15871593
if (this.passed) {
1588-
this.reporter.ok(this.nesting, this.loc, this.testNumber, this.name, report.details, report.directive);
1594+
this.reporter.ok(
1595+
this.nesting, this.loc, this.testNumber, this.name,
1596+
report.details, report.directive, this.testId,
1597+
);
15891598
} else {
1590-
this.reporter.fail(this.nesting, this.loc, this.testNumber, this.name, report.details, report.directive);
1599+
this.reporter.fail(
1600+
this.nesting, this.loc, this.testNumber, this.name,
1601+
report.details, report.directive, this.testId,
1602+
);
15911603
}
15921604

15931605
for (let i = 0; i < this.diagnostics.length; i++) {
@@ -1601,7 +1613,7 @@ class Test extends AsyncResource {
16011613
}
16021614
this.#reportedSubtest = true;
16031615
this.parent.reportStarted();
1604-
this.reporter.start(this.nesting, this.loc, this.name);
1616+
this.reporter.start(this.nesting, this.loc, this.name, this.testId);
16051617
}
16061618

16071619
clearExecutionTime() {

lib/internal/test_runner/tests_stream.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,39 @@ class TestsStream extends Readable {
3434
}
3535
}
3636

37-
fail(nesting, loc, testNumber, name, details, directive) {
37+
fail(nesting, loc, testNumber, name, details, directive, testId) {
3838
this[kEmitMessage]('test:fail', {
3939
__proto__: null,
4040
name,
4141
nesting,
4242
testNumber,
43+
testId,
4344
details,
4445
...loc,
4546
...directive,
4647
});
4748
}
4849

49-
ok(nesting, loc, testNumber, name, details, directive) {
50+
ok(nesting, loc, testNumber, name, details, directive, testId) {
5051
this[kEmitMessage]('test:pass', {
5152
__proto__: null,
5253
name,
5354
nesting,
5455
testNumber,
56+
testId,
5557
details,
5658
...loc,
5759
...directive,
5860
});
5961
}
6062

61-
complete(nesting, loc, testNumber, name, details, directive) {
63+
complete(nesting, loc, testNumber, name, details, directive, testId) {
6264
this[kEmitMessage]('test:complete', {
6365
__proto__: null,
6466
name,
6567
nesting,
6668
testNumber,
69+
testId,
6770
details,
6871
...loc,
6972
...directive,
@@ -91,31 +94,34 @@ class TestsStream extends Readable {
9194
return { __proto__: null, expectFailure: expectation ?? true };
9295
}
9396

94-
enqueue(nesting, loc, name, type) {
97+
enqueue(nesting, loc, name, type, testId) {
9598
this[kEmitMessage]('test:enqueue', {
9699
__proto__: null,
97100
nesting,
98101
name,
99102
type,
103+
testId,
100104
...loc,
101105
});
102106
}
103107

104-
dequeue(nesting, loc, name, type) {
108+
dequeue(nesting, loc, name, type, testId) {
105109
this[kEmitMessage]('test:dequeue', {
106110
__proto__: null,
107111
nesting,
108112
name,
109113
type,
114+
testId,
110115
...loc,
111116
});
112117
}
113118

114-
start(nesting, loc, name) {
119+
start(nesting, loc, name, testId) {
115120
this[kEmitMessage]('test:start', {
116121
__proto__: null,
117122
nesting,
118123
name,
124+
testId,
119125
...loc,
120126
});
121127
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
const { describe, it } = require('node:test');
3+
const assert = require('node:assert');
4+
5+
// Factory that creates subtests at the SAME source location.
6+
// Multiple concurrent `it` blocks calling this will have subtests
7+
// sharing file:line:column — but each should get a distinct testId.
8+
function makeSubtest(shouldFail) {
9+
return async function(t) {
10+
await t.test('e2e', async () => {
11+
if (shouldFail) assert.fail('intentional');
12+
});
13+
};
14+
}
15+
16+
describe('suite', { concurrency: 10_000 }, () => {
17+
it('test-A (passes)', makeSubtest(false));
18+
it('test-B (passes)', makeSubtest(false));
19+
it('test-C (fails)', makeSubtest(true));
20+
it('test-D (passes)', makeSubtest(false));
21+
});
Lines changed: 76 additions & 0 deletions

0 commit comments

Comments
 (0)