Skip to content

Commit 0f69b6c

Browse files
MrJithildanielleadams
authored andcommittedJan 3, 2023
test_runner: fix afterEach not running on test failures
test_runner: fix afterEach not running on test failures PR-URL: #45204 Fixes: #45192 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
1 parent 3053c65 commit 0f69b6c

File tree

6 files changed

+211
-22
lines changed

6 files changed

+211
-22
lines changed
 

‎lib/internal/test_runner/test.js

+18-10
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const {
4141
const {
4242
createDeferredPromise,
4343
kEmptyObject,
44+
once: runOnce,
4445
} = require('internal/util');
4546
const { isPromise } = require('internal/util/types');
4647
const {
@@ -482,8 +483,14 @@ class Test extends AsyncResource {
482483
return;
483484
}
484485

486+
const { args, ctx } = this.getRunArgs();
487+
const afterEach = runOnce(async () => {
488+
if (this.parent?.hooks.afterEach.length > 0) {
489+
await this.parent[kRunHook]('afterEach', { args, ctx });
490+
}
491+
});
492+
485493
try {
486-
const { args, ctx } = this.getRunArgs();
487494
if (this.parent?.hooks.beforeEach.length > 0) {
488495
await this.parent[kRunHook]('beforeEach', { args, ctx });
489496
}
@@ -518,12 +525,10 @@ class Test extends AsyncResource {
518525
return;
519526
}
520527

521-
if (this.parent?.hooks.afterEach.length > 0) {
522-
await this.parent[kRunHook]('afterEach', { args, ctx });
523-
}
524-
528+
await afterEach();
525529
this.pass();
526530
} catch (err) {
531+
try { await afterEach(); } catch { /* test is already failing, let's the error */ }
527532
if (isTestFailureError(err)) {
528533
if (err.failureType === kTestTimeoutFailure) {
529534
this.cancel(err);
@@ -728,6 +733,12 @@ class Suite extends Test {
728733
}
729734

730735
async run() {
736+
const hookArgs = this.getRunArgs();
737+
const afterEach = runOnce(async () => {
738+
if (this.parent?.hooks.afterEach.length > 0) {
739+
await this.parent[kRunHook]('afterEach', hookArgs);
740+
}
741+
});
731742
try {
732743
this.parent.activeSubtests++;
733744
await this.buildSuite;
@@ -739,7 +750,6 @@ class Suite extends Test {
739750
return;
740751
}
741752

742-
const hookArgs = this.getRunArgs();
743753

744754
if (this.parent?.hooks.beforeEach.length > 0) {
745755
await this.parent[kRunHook]('beforeEach', hookArgs);
@@ -753,13 +763,11 @@ class Suite extends Test {
753763

754764
await SafePromiseRace([promise, stopPromise]);
755765
await this[kRunHook]('after', hookArgs);
756-
757-
if (this.parent?.hooks.afterEach.length > 0) {
758-
await this.parent[kRunHook]('afterEach', hookArgs);
759-
}
766+
await afterEach();
760767

761768
this.pass();
762769
} catch (err) {
770+
try { await afterEach(); } catch { /* test is already failing, let's the error */ }
763771
if (isTestFailureError(err)) {
764772
this.fail(err);
765773
} else {

‎lib/internal/util.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ function once(callback) {
450450
return function(...args) {
451451
if (called) return;
452452
called = true;
453-
ReflectApply(callback, this, args);
453+
return ReflectApply(callback, this, args);
454454
};
455455
}
456456

‎test/message/test_runner_describe_it.out

-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ not ok 4 - sync fail todo with message # TODO this is a failing todo
4242
*
4343
*
4444
*
45-
*
46-
*
4745
...
4846
# Subtest: sync skip pass
4947
ok 5 - sync skip pass # SKIP

‎test/message/test_runner_hooks.js

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Flags: --no-warnings
22
'use strict';
3-
require('../common');
3+
const common = require('../common');
44
const assert = require('assert');
55
const { test, describe, it, before, after, beforeEach, afterEach } = require('node:test');
66

@@ -76,6 +76,18 @@ describe('afterEach throws', () => {
7676
it('2', () => {});
7777
});
7878

79+
describe('afterEach when test fails', () => {
80+
afterEach(common.mustCall(2));
81+
it('1', () => { throw new Error('test'); });
82+
it('2', () => {});
83+
});
84+
85+
describe('afterEach throws and test fails', () => {
86+
afterEach(() => { throw new Error('afterEach'); });
87+
it('1', () => { throw new Error('test'); });
88+
it('2', () => {});
89+
});
90+
7991
test('test hooks', async (t) => {
8092
const testArr = [];
8193
t.beforeEach((t) => testArr.push('beforeEach ' + t.name));
@@ -111,3 +123,16 @@ test('t.afterEach throws', async (t) => {
111123
await t.test('1', () => {});
112124
await t.test('2', () => {});
113125
});
126+
127+
128+
test('afterEach when test fails', async (t) => {
129+
t.afterEach(common.mustCall(2));
130+
await t.test('1', () => { throw new Error('test'); });
131+
await t.test('2', () => {});
132+
});
133+
134+
test('afterEach throws and test fails', async (t) => {
135+
afterEach(() => { throw new Error('afterEach'); });
136+
await t.test('1', () => { throw new Error('test'); });
137+
await t.test('2', () => {});
138+
});

‎test/message/test_runner_hooks.out

+166-6
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,86 @@ not ok 5 - afterEach throws
189189
error: '2 subtests failed'
190190
code: 'ERR_TEST_FAILURE'
191191
...
192+
# Subtest: afterEach when test fails
193+
# Subtest: 1
194+
not ok 1 - 1
195+
---
196+
duration_ms: *
197+
failureType: 'testCodeFailure'
198+
error: 'test'
199+
code: 'ERR_TEST_FAILURE'
200+
stack: |-
201+
*
202+
*
203+
*
204+
*
205+
*
206+
*
207+
*
208+
*
209+
*
210+
*
211+
...
212+
# Subtest: 2
213+
ok 2 - 2
214+
---
215+
duration_ms: *
216+
...
217+
1..2
218+
not ok 6 - afterEach when test fails
219+
---
220+
duration_ms: *
221+
failureType: 'subtestsFailed'
222+
error: '1 subtest failed'
223+
code: 'ERR_TEST_FAILURE'
224+
...
225+
# Subtest: afterEach throws and test fails
226+
# Subtest: 1
227+
not ok 1 - 1
228+
---
229+
duration_ms: *
230+
failureType: 'testCodeFailure'
231+
error: 'test'
232+
code: 'ERR_TEST_FAILURE'
233+
stack: |-
234+
*
235+
*
236+
*
237+
*
238+
*
239+
*
240+
*
241+
*
242+
*
243+
*
244+
...
245+
# Subtest: 2
246+
not ok 2 - 2
247+
---
248+
duration_ms: *
249+
failureType: 'hookFailed'
250+
error: 'failed running afterEach hook'
251+
code: 'ERR_TEST_FAILURE'
252+
stack: |-
253+
*
254+
*
255+
*
256+
*
257+
*
258+
*
259+
*
260+
*
261+
*
262+
*
263+
...
264+
1..2
265+
not ok 7 - afterEach throws and test fails
266+
---
267+
duration_ms: *
268+
failureType: 'subtestsFailed'
269+
error: '2 subtests failed'
270+
code: 'ERR_TEST_FAILURE'
271+
...
192272
# Subtest: test hooks
193273
# Subtest: 1
194274
ok 1 - 1
@@ -217,7 +297,7 @@ not ok 5 - afterEach throws
217297
duration_ms: *
218298
...
219299
1..3
220-
ok 6 - test hooks
300+
ok 8 - test hooks
221301
---
222302
duration_ms: *
223303
...
@@ -261,7 +341,7 @@ ok 6 - test hooks
261341
*
262342
...
263343
1..2
264-
not ok 7 - t.beforeEach throws
344+
not ok 9 - t.beforeEach throws
265345
---
266346
duration_ms: *
267347
failureType: 'subtestsFailed'
@@ -308,17 +388,97 @@ not ok 7 - t.beforeEach throws
308388
*
309389
...
310390
1..2
311-
not ok 8 - t.afterEach throws
391+
not ok 10 - t.afterEach throws
392+
---
393+
duration_ms: *
394+
failureType: 'subtestsFailed'
395+
error: '2 subtests failed'
396+
code: 'ERR_TEST_FAILURE'
397+
...
398+
# Subtest: afterEach when test fails
399+
# Subtest: 1
400+
not ok 1 - 1
401+
---
402+
duration_ms: *
403+
failureType: 'testCodeFailure'
404+
error: 'test'
405+
code: 'ERR_TEST_FAILURE'
406+
stack: |-
407+
*
408+
*
409+
*
410+
*
411+
*
412+
*
413+
*
414+
*
415+
*
416+
*
417+
...
418+
# Subtest: 2
419+
ok 2 - 2
420+
---
421+
duration_ms: *
422+
...
423+
1..2
424+
not ok 11 - afterEach when test fails
425+
---
426+
duration_ms: *
427+
failureType: 'subtestsFailed'
428+
error: '1 subtest failed'
429+
code: 'ERR_TEST_FAILURE'
430+
...
431+
# Subtest: afterEach throws and test fails
432+
# Subtest: 1
433+
not ok 1 - 1
434+
---
435+
duration_ms: *
436+
failureType: 'testCodeFailure'
437+
error: 'test'
438+
code: 'ERR_TEST_FAILURE'
439+
stack: |-
440+
*
441+
*
442+
*
443+
*
444+
*
445+
*
446+
*
447+
*
448+
*
449+
*
450+
...
451+
# Subtest: 2
452+
not ok 2 - 2
453+
---
454+
duration_ms: *
455+
failureType: 'hookFailed'
456+
error: 'failed running afterEach hook'
457+
code: 'ERR_TEST_FAILURE'
458+
stack: |-
459+
*
460+
*
461+
*
462+
*
463+
*
464+
*
465+
*
466+
*
467+
*
468+
*
469+
...
470+
1..2
471+
not ok 12 - afterEach throws and test fails
312472
---
313473
duration_ms: *
314474
failureType: 'subtestsFailed'
315475
error: '2 subtests failed'
316476
code: 'ERR_TEST_FAILURE'
317477
...
318-
1..8
319-
# tests 8
478+
1..12
479+
# tests 12
320480
# pass 2
321-
# fail 6
481+
# fail 10
322482
# cancelled 0
323483
# skipped 0
324484
# todo 0

‎test/message/test_runner_output.out

-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ not ok 4 - sync fail todo with message # TODO this is a failing todo
4242
*
4343
*
4444
*
45-
*
46-
*
4745
...
4846
# Subtest: sync skip pass
4947
ok 5 - sync skip pass # SKIP

0 commit comments

Comments
 (0)