mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
lib: allow checking the test result from afterEach
PR-URL: https://github.com/nodejs/node/pull/51485 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
This commit is contained in:
@@ -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]();
|
||||
|
||||
|
||||
19
test/fixtures/test-runner/output/hooks.js
vendored
19
test/fixtures/test-runner/output/hooks.js
vendored
@@ -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'); });
|
||||
|
||||
49
test/fixtures/test-runner/output/hooks.snapshot
vendored
49
test/fixtures/test-runner/output/hooks.snapshot
vendored
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -155,6 +155,7 @@ true !== false
|
||||
<testcase name="+sync throw fail" time="*" classname="test" failure="thrown from subtest sync throw fail">
|
||||
<failure type="testCodeFailure" message="thrown from subtest sync throw fail">
|
||||
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
|
||||
<testcase name="sync throw fails at first" time="*" classname="test" failure="thrown from subtest sync throw fails at first">
|
||||
<failure type="testCodeFailure" message="thrown from subtest sync throw fails at first">
|
||||
Error [ERR_TEST_FAILURE]: thrown from subtest sync throw fails at first
|
||||
*
|
||||
* {
|
||||
code: 'ERR_TEST_FAILURE',
|
||||
failureType: 'testCodeFailure',
|
||||
|
||||
Reference in New Issue
Block a user