From 4b583bfcc57ac315eafc822a6a2c127379e07ba6 Mon Sep 17 00:00:00 2001 From: Tim Stableford Date: Fri, 19 Jan 2024 14:56:06 +0000 Subject: [PATCH] lib: allow checking the test result from afterEach PR-URL: https://github.com/nodejs/node/pull/51485 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Moshe Atlow --- lib/internal/test_runner/test.js | 23 +++++++-- test/fixtures/test-runner/output/hooks.js | 19 +++++++ .../test-runner/output/hooks.snapshot | 49 ++++++++++++++++--- .../output/hooks_spec_reporter.snapshot | 28 +++++++++-- .../output/junit_reporter.snapshot | 2 + 5 files changed, 107 insertions(+), 14 deletions(-) diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index e38b1a67c09660..ee2c345e7a0403 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -132,6 +132,14 @@ class TestContext { return this.#test.name; } + get error() { + return this.#test.error; + } + + get passed() { + return this.#test.passed; + } + diagnostic(message) { this.#test.diagnostic(message); } @@ -639,12 +647,17 @@ class Test extends AsyncResource { return; } - await afterEach(); - await after(); this.pass(); + try { + await afterEach(); + await after(); + } catch (err) { + // If one of the after hooks has thrown unset endTime so that the + // catch below can do its cancel/fail logic. + this.endTime = null; + throw err; + } } catch (err) { - try { await afterEach(); } catch { /* test is already failing, let's ignore the error */ } - try { await after(); } catch { /* Ignore error. */ } if (isTestFailureError(err)) { if (err.failureType === kTestTimeoutFailure) { this.#cancel(err); @@ -654,6 +667,8 @@ class Test extends AsyncResource { } else { this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure)); } + try { await afterEach(); } catch { /* test is already failing, let's ignore the error */ } + try { await after(); } catch { /* Ignore error. */ } } finally { stopPromise?.[SymbolDispose](); diff --git a/test/fixtures/test-runner/output/hooks.js b/test/fixtures/test-runner/output/hooks.js index 531615fd97d69b..38de02e1119da4 100644 --- a/test/fixtures/test-runner/output/hooks.js +++ b/test/fixtures/test-runner/output/hooks.js @@ -152,6 +152,25 @@ test('afterEach when test fails', async (t) => { await t.test('2', () => {}); }); +test('afterEach context when test passes', async (t) => { + t.afterEach(common.mustCall((ctx) => { + assert.strictEqual(ctx.name, '1'); + assert.strictEqual(ctx.passed, true); + assert.strictEqual(ctx.error, null); + })); + await t.test('1', () => {}); +}); + +test('afterEach context when test fails', async (t) => { + const err = new Error('test'); + t.afterEach(common.mustCall((ctx) => { + assert.strictEqual(ctx.name, '1'); + assert.strictEqual(ctx.passed, false); + assert.strictEqual(ctx.error, err); + })); + await t.test('1', () => { throw err }); +}); + test('afterEach throws and test fails', async (t) => { t.after(common.mustCall()); t.afterEach(() => { throw new Error('afterEach'); }); diff --git a/test/fixtures/test-runner/output/hooks.snapshot b/test/fixtures/test-runner/output/hooks.snapshot index edb455b025ff58..c9c1632e2b9e45 100644 --- a/test/fixtures/test-runner/output/hooks.snapshot +++ b/test/fixtures/test-runner/output/hooks.snapshot @@ -505,6 +505,41 @@ not ok 12 - afterEach when test fails error: '1 subtest failed' code: 'ERR_TEST_FAILURE' ... +# Subtest: afterEach context when test passes + # Subtest: 1 + ok 1 - 1 + --- + duration_ms: * + ... + 1..1 +ok 13 - afterEach context when test passes + --- + duration_ms: * + ... +# Subtest: afterEach context when test fails + # Subtest: 1 + not ok 1 - 1 + --- + duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' + failureType: 'testCodeFailure' + error: 'test' + code: 'ERR_TEST_FAILURE' + stack: |- + * + * + * + * + ... + 1..1 +not ok 14 - afterEach context when test fails + --- + duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' + failureType: 'subtestsFailed' + error: '1 subtest failed' + code: 'ERR_TEST_FAILURE' + ... # Subtest: afterEach throws and test fails # Subtest: 1 not ok 1 - 1 @@ -546,7 +581,7 @@ not ok 12 - afterEach when test fails * ... 1..2 -not ok 13 - afterEach throws and test fails +not ok 15 - afterEach throws and test fails --- duration_ms: * location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' @@ -555,7 +590,7 @@ not ok 13 - afterEach throws and test fails code: 'ERR_TEST_FAILURE' ... # Subtest: t.after() is called if test body throws -not ok 14 - t.after() is called if test body throws +not ok 16 - t.after() is called if test body throws --- duration_ms: * location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' @@ -580,7 +615,7 @@ not ok 14 - t.after() is called if test body throws code: 'ERR_TEST_FAILURE' ... 1..1 -not ok 15 - run after when before throws +not ok 17 - run after when before throws --- duration_ms: * type: 'suite' @@ -599,15 +634,15 @@ not ok 15 - run after when before throws * * ... -1..15 +1..17 # before 1 called # before 2 called # after 1 called # after 2 called -# tests 39 +# tests 43 # suites 9 -# pass 14 -# fail 22 +# pass 16 +# fail 24 # cancelled 3 # skipped 0 # todo 0 diff --git a/test/fixtures/test-runner/output/hooks_spec_reporter.snapshot b/test/fixtures/test-runner/output/hooks_spec_reporter.snapshot index 4cd47bf042b95d..c9b749d571674f 100644 --- a/test/fixtures/test-runner/output/hooks_spec_reporter.snapshot +++ b/test/fixtures/test-runner/output/hooks_spec_reporter.snapshot @@ -258,6 +258,20 @@ 2 (*ms) afterEach when test fails (*ms) + afterEach context when test passes + 1 (*ms) + afterEach context when test passes (*ms) + + afterEach context when test fails + 1 (*ms) + Error: test + * + * + * + * + + afterEach context when test fails (*ms) + afterEach throws and test fails 1 (*ms) Error: test @@ -315,10 +329,10 @@ before 2 called after 1 called after 2 called - tests 39 + tests 43 suites 9 - pass 14 - fail 22 + pass 16 + fail 24 cancelled 3 skipped 0 todo 0 @@ -551,6 +565,14 @@ * * +* + 1 (*ms) + Error: test + * + * + * + * + * 1 (*ms) Error: test diff --git a/test/fixtures/test-runner/output/junit_reporter.snapshot b/test/fixtures/test-runner/output/junit_reporter.snapshot index e0a4c331dd5c22..562c7696cbd0ec 100644 --- a/test/fixtures/test-runner/output/junit_reporter.snapshot +++ b/test/fixtures/test-runner/output/junit_reporter.snapshot @@ -155,6 +155,7 @@ true !== false Error [ERR_TEST_FAILURE]: thrown from subtest sync throw fail + * * { code: 'ERR_TEST_FAILURE', failureType: 'testCodeFailure', @@ -338,6 +339,7 @@ Error [ERR_TEST_FAILURE]: thrown from callback async throw Error [ERR_TEST_FAILURE]: thrown from subtest sync throw fails at first + * * { code: 'ERR_TEST_FAILURE', failureType: 'testCodeFailure',