Skip to content

Commit fc9ba17

Browse files
MoLowmarco-ippolito
authored andcommittedMay 2, 2024
test_runner: add test:complete event to reflect execution order
PR-URL: #51909 Fixes: #51907 Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
1 parent 503c034 commit fc9ba17

File tree

4 files changed

+84
-13
lines changed

4 files changed

+84
-13
lines changed
 

‎doc/api/test.md

+48
Original file line numberDiff line numberDiff line change
@@ -2445,6 +2445,9 @@ A successful call to [`run()`][] method will return a new {TestsStream}
24452445
object, streaming a series of events representing the execution of the tests.
24462446
`TestsStream` will emit events, in the order of the tests definition
24472447

2448+
Some of the events are guaranteed to be emitted in the same order as the tests
2449+
are defined, while others are emitted in the order that the tests execute.
2450+
24482451
### Event: `'test:coverage'`
24492452

24502453
* `data` {Object}
@@ -2491,6 +2494,34 @@ object, streaming a series of events representing the execution of the tests.
24912494

24922495
Emitted when code coverage is enabled and all tests have completed.
24932496

2497+
### Event: `'test:complete'`
2498+
2499+
* `data` {Object}
2500+
* `column` {number|undefined} The column number where the test is defined, or
2501+
`undefined` if the test was run through the REPL.
2502+
* `details` {Object} Additional execution metadata.
2503+
* `passed` {boolean} Whether the test passed or not.
2504+
* `duration_ms` {number} The duration of the test in milliseconds.
2505+
* `error` {Error|undefined} An error wrapping the error thrown by the test
2506+
if it did not pass.
2507+
* `cause` {Error} The actual error thrown by the test.
2508+
* `type` {string|undefined} The type of the test, used to denote whether
2509+
this is a suite.
2510+
* `file` {string|undefined} The path of the test file,
2511+
`undefined` if test was run through the REPL.
2512+
* `line` {number|undefined} The line number where the test is defined, or
2513+
`undefined` if the test was run through the REPL.
2514+
* `name` {string} The test name.
2515+
* `nesting` {number} The nesting level of the test.
2516+
* `testNumber` {number} The ordinal number of the test.
2517+
* `todo` {string|boolean|undefined} Present if [`context.todo`][] is called
2518+
* `skip` {string|boolean|undefined} Present if [`context.skip`][] is called
2519+
2520+
Emitted when a test completes its execution.
2521+
This event is not emitted in the same order as the tests are
2522+
defined.
2523+
The corresponding declaration ordered events are `'test:pass'` and `'test:fail'`.
2524+
24942525
### Event: `'test:dequeue'`
24952526

24962527
* `data` {Object}
@@ -2504,6 +2535,8 @@ Emitted when code coverage is enabled and all tests have completed.
25042535
* `nesting` {number} The nesting level of the test.
25052536

25062537
Emitted when a test is dequeued, right before it is executed.
2538+
This event is not guaranteed to be emitted in the same order as the tests are
2539+
defined. The corresponding declaration ordered event is `'test:start'`.
25072540

25082541
### Event: `'test:diagnostic'`
25092542

@@ -2518,6 +2551,8 @@ Emitted when a test is dequeued, right before it is executed.
25182551
* `nesting` {number} The nesting level of the test.
25192552

25202553
Emitted when [`context.diagnostic`][] is called.
2554+
This event is guaranteed to be emitted in the same order as the tests are
2555+
defined.
25212556

25222557
### Event: `'test:enqueue'`
25232558

@@ -2555,6 +2590,9 @@ Emitted when a test is enqueued for execution.
25552590
* `skip` {string|boolean|undefined} Present if [`context.skip`][] is called
25562591

25572592
Emitted when a test fails.
2593+
This event is guaranteed to be emitted in the same order as the tests are
2594+
defined.
2595+
The corresponding execution ordered event is `'test:complete'`.
25582596

25592597
### Event: `'test:pass'`
25602598

@@ -2576,6 +2614,9 @@ Emitted when a test fails.
25762614
* `skip` {string|boolean|undefined} Present if [`context.skip`][] is called
25772615

25782616
Emitted when a test passes.
2617+
This event is guaranteed to be emitted in the same order as the tests are
2618+
defined.
2619+
The corresponding execution ordered event is `'test:complete'`.
25792620

25802621
### Event: `'test:plan'`
25812622

@@ -2590,6 +2631,8 @@ Emitted when a test passes.
25902631
* `count` {number} The number of subtests that have ran.
25912632

25922633
Emitted when all subtests have completed for a given test.
2634+
This event is guaranteed to be emitted in the same order as the tests are
2635+
defined.
25932636

25942637
### Event: `'test:start'`
25952638

@@ -2606,6 +2649,7 @@ Emitted when all subtests have completed for a given test.
26062649
Emitted when a test starts reporting its own and its subtests status.
26072650
This event is guaranteed to be emitted in the same order as the tests are
26082651
defined.
2652+
The corresponding execution ordered event is `'test:dequeue'`.
26092653

26102654
### Event: `'test:stderr'`
26112655

@@ -2619,6 +2663,8 @@ defined.
26192663

26202664
Emitted when a running test writes to `stderr`.
26212665
This event is only emitted if `--test` flag is passed.
2666+
This event is not guaranteed to be emitted in the same order as the tests are
2667+
defined.
26222668

26232669
### Event: `'test:stdout'`
26242670

@@ -2632,6 +2678,8 @@ This event is only emitted if `--test` flag is passed.
26322678

26332679
Emitted when a running test writes to `stdout`.
26342680
This event is only emitted if `--test` flag is passed.
2681+
This event is not guaranteed to be emitted in the same order as the tests are
2682+
defined.
26352683

26362684
### Event: `'test:watch:drained'`
26372685

‎lib/internal/test_runner/test.js

+21-10
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,10 @@ class Test extends AsyncResource {
724724
this.mock?.reset();
725725

726726
if (this.parent !== null) {
727+
const report = this.getReportDetails();
728+
report.details.passed = this.passed;
729+
this.reporter.complete(this.nesting, this.loc, this.testNumber, this.name, report.details, report.directive);
730+
727731
this.parent.activeSubtests--;
728732
this.parent.addReadySubtest(this);
729733
this.parent.processReadySubtestRange(false);
@@ -804,13 +808,7 @@ class Test extends AsyncResource {
804808
return Number(this.endTime - this.startTime) / 1_000_000;
805809
}
806810

807-
report() {
808-
countCompletedTest(this);
809-
if (this.subtests.length > 0) {
810-
this.reporter.plan(this.subtests[0].nesting, this.loc, this.subtests.length);
811-
} else {
812-
this.reportStarted();
813-
}
811+
getReportDetails() {
814812
let directive;
815813
const details = { __proto__: null, duration_ms: this.duration() };
816814

@@ -823,12 +821,25 @@ class Test extends AsyncResource {
823821
if (this.reportedType) {
824822
details.type = this.reportedType;
825823
}
824+
if (!this.passed) {
825+
details.error = this.error;
826+
}
827+
return { __proto__: null, details, directive };
828+
}
829+
830+
report() {
831+
countCompletedTest(this);
832+
if (this.subtests.length > 0) {
833+
this.reporter.plan(this.subtests[0].nesting, this.loc, this.subtests.length);
834+
} else {
835+
this.reportStarted();
836+
}
837+
const report = this.getReportDetails();
826838

827839
if (this.passed) {
828-
this.reporter.ok(this.nesting, this.loc, this.testNumber, this.name, details, directive);
840+
this.reporter.ok(this.nesting, this.loc, this.testNumber, this.name, report.details, report.directive);
829841
} else {
830-
details.error = this.error;
831-
this.reporter.fail(this.nesting, this.loc, this.testNumber, this.name, details, directive);
842+
this.reporter.fail(this.nesting, this.loc, this.testNumber, this.name, report.details, report.directive);
832843
}
833844

834845
for (let i = 0; i < this.diagnostics.length; i++) {

‎lib/internal/test_runner/tests_stream.js

+12
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ class TestsStream extends Readable {
5353
});
5454
}
5555

56+
complete(nesting, loc, testNumber, name, details, directive) {
57+
this[kEmitMessage]('test:complete', {
58+
__proto__: null,
59+
name,
60+
nesting,
61+
testNumber,
62+
details,
63+
...loc,
64+
...directive,
65+
});
66+
}
67+
5668
plan(nesting, loc, count) {
5769
this[kEmitMessage]('test:plan', {
5870
__proto__: null,

‎test/parallel/test-runner-reporters.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ describe('node:test reporters', { concurrency: true }, () => {
9696
testFile]);
9797
assert.strictEqual(child.stderr.toString(), '');
9898
const stdout = child.stdout.toString();
99-
assert.match(stdout, /{"test:enqueue":5,"test:dequeue":5,"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/);
99+
assert.match(stdout, /{"test:enqueue":5,"test:dequeue":5,"test:complete":5,"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/);
100100
assert.strictEqual(stdout.slice(0, filename.length + 2), `${filename} {`);
101101
});
102102
});
@@ -108,7 +108,7 @@ describe('node:test reporters', { concurrency: true }, () => {
108108
assert.strictEqual(child.stderr.toString(), '');
109109
assert.match(
110110
child.stdout.toString(),
111-
/^package: reporter-cjs{"test:enqueue":5,"test:dequeue":5,"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/,
111+
/^package: reporter-cjs{"test:enqueue":5,"test:dequeue":5,"test:complete":5,"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/,
112112
);
113113
});
114114

@@ -119,7 +119,7 @@ describe('node:test reporters', { concurrency: true }, () => {
119119
assert.strictEqual(child.stderr.toString(), '');
120120
assert.match(
121121
child.stdout.toString(),
122-
/^package: reporter-esm{"test:enqueue":5,"test:dequeue":5,"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/,
122+
/^package: reporter-esm{"test:enqueue":5,"test:dequeue":5,"test:complete":5,"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/,
123123
);
124124
});
125125

0 commit comments

Comments
 (0)
Please sign in to comment.