Skip to content

Commit

Permalink
test_runner: remove promises returned by t.test()
Browse files Browse the repository at this point in the history
This commit updates the TestContext.prototype.test() API to no
longer return a Promise.

Fixes: #51292
  • Loading branch information
cjihrig committed Jan 20, 2025
1 parent c7a54bb commit 3788e00
Show file tree
Hide file tree
Showing 11 changed files with 36 additions and 76 deletions.
62 changes: 26 additions & 36 deletions doc/api/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ top level test with two subtests.

```js
test('top level test', async (t) => {
await t.test('subtest 1', (t) => {
t.test('subtest 1', (t) => {
assert.strictEqual(1, 1);
});

await t.test('subtest 2', (t) => {
t.test('subtest 2', (t) => {
assert.strictEqual(2, 2);
});
});
Expand All @@ -118,12 +118,7 @@ test('top level test', async (t) => {
> **Note:** `beforeEach` and `afterEach` hooks are triggered
> between each subtest execution.
In this example, `await` is used to ensure that both subtests have completed.
This is necessary because tests do not wait for their subtests to
complete, unlike tests created within suites.
Any subtests that are still outstanding when their parent finishes
are cancelled and treated as failures. Any subtest failures cause the parent
test to fail.
Any subtest failures cause the parent test to fail.

## Skipping tests

Expand Down Expand Up @@ -241,20 +236,20 @@ that are not executed are omitted from the test runner output.
// The suite's 'only' option is set, so these tests are run.
test('this test is run', { only: true }, async (t) => {
// Within this test, all subtests are run by default.
await t.test('running subtest');
t.test('running subtest');

// The test context can be updated to run subtests with the 'only' option.
t.runOnly(true);
await t.test('this subtest is now skipped');
await t.test('this subtest is run', { only: true });
t.test('this subtest is now skipped');
t.test('this subtest is run', { only: true });

// Switch the context back to execute all tests.
t.runOnly(false);
await t.test('this subtest is now run');
t.test('this subtest is now run');

// Explicitly do not run these tests.
await t.test('skipped subtest 3', { only: false });
await t.test('skipped subtest 4', { skip: true });
t.test('skipped subtest 3', { only: false });
t.test('skipped subtest 4', { skip: true });
});

// The 'only' option is not set, so this test is skipped.
Expand Down Expand Up @@ -309,13 +304,13 @@ multiple times (e.g. `--test-name-pattern="test 1"`,

```js
test('test 1', async (t) => {
await t.test('test 2');
await t.test('test 3');
t.test('test 2');
t.test('test 3');
});

test('Test 4', async (t) => {
await t.test('Test 5');
await t.test('test 6');
t.test('Test 5');
t.test('test 6');
});
```

Expand Down Expand Up @@ -3175,12 +3170,9 @@ before each subtest of the current test.
```js
test('top level test', async (t) => {
t.beforeEach((t) => t.diagnostic(`about to run ${t.name}`));
await t.test(
'This is a subtest',
(t) => {
assert.ok('some relevant assertion here');
},
);
t.test('This is a subtest', (t) => {
assert.ok('some relevant assertion here');
});
});
```

Expand Down Expand Up @@ -3238,12 +3230,9 @@ after each subtest of the current test.
```js
test('top level test', async (t) => {
t.afterEach((t) => t.diagnostic(`finished running ${t.name}`));
await t.test(
'This is a subtest',
(t) => {
assert.ok('some relevant assertion here');
},
);
t.test('This is a subtest', (t) => {
assert.ok('some relevant assertion here');
});
});
```

Expand Down Expand Up @@ -3458,10 +3447,8 @@ no-op.
test('top level test', (t) => {
// The test context can be set to run subtests with the 'only' option.
t.runOnly(true);
return Promise.all([
t.test('this subtest is now skipped'),
t.test('this subtest is run', { only: true }),
]);
t.test('this subtest is now skipped');
t.test('this subtest is run', { only: true });
});
```

Expand Down Expand Up @@ -3533,6 +3520,10 @@ added:
- v18.0.0
- v16.17.0
changes:
- version:
- REPLACEME
pr-url: https://github.com/nodejs/node/pull/56664
description: This function no longer returns a `Promise`.
- version:
- v18.8.0
- v16.18.0
Expand Down Expand Up @@ -3577,14 +3568,13 @@ changes:
to this function is a [`TestContext`][] object. If the test uses callbacks,
the callback function is passed as the second argument. **Default:** A no-op
function.
* Returns: {Promise} Fulfilled with `undefined` once the test completes.

This function is used to create subtests under the current test. This function
behaves in the same fashion as the top level [`test()`][] function.

```js
test('top level test', async (t) => {
await t.test(
t.test(
'This is a subtest',
{ only: false, skip: false, concurrency: 1, todo: false, plan: 1 },
(t) => {
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/test_runner/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ class TestContext {
Test, name, options, fn, overrides,
);

return subtest.start();
subtest.start();
}

before(fn, options) {
Expand Down
2 changes: 0 additions & 2 deletions test/fixtures/test-runner/output/dot_reporter.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@ Failed tests:
*
*
*
*
*
✖ subtest sync throw fails (*ms)
'2 subtests failed'
✖ timed out async test (*ms)
Expand Down
5 changes: 0 additions & 5 deletions test/fixtures/test-runner/output/hooks.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,6 @@ not ok 16 - t.after throws - no subtests
*
*
*
*
...
1..2
not ok 17 - t.beforeEach throws
Expand Down Expand Up @@ -607,8 +606,6 @@ not ok 17 - t.beforeEach throws
*
*
*
*
*
...
# Subtest: 2
not ok 2 - 2
Expand All @@ -629,7 +626,6 @@ not ok 17 - t.beforeEach throws
*
*
*
*
...
1..2
not ok 18 - t.afterEach throws
Expand Down Expand Up @@ -757,7 +753,6 @@ not ok 21 - afterEach context when test fails
*
*
*
*
...
1..2
not ok 22 - afterEach throws and test fails
Expand Down
10 changes: 0 additions & 10 deletions test/fixtures/test-runner/output/hooks_spec_reporter.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,6 @@
*
*
*
*

t.beforeEach throws (*ms)
t.afterEach throws
Expand All @@ -296,8 +295,6 @@
*
*
*
*
*

2 (*ms)
Error: afterEach
Expand All @@ -310,7 +307,6 @@
*
*
*
*

t.afterEach throws (*ms)
afterEach when test fails
Expand Down Expand Up @@ -364,7 +360,6 @@
*
*
*
*

afterEach throws and test fails (*ms)
t.after() is called if test body throws (*ms)
Expand Down Expand Up @@ -674,7 +669,6 @@
*
*
*
*

*
1 (*ms)
Expand All @@ -687,8 +681,6 @@
*
*
*
*
*

*
2 (*ms)
Expand All @@ -702,7 +694,6 @@
*
*
*
*

*
1 (*ms)
Expand Down Expand Up @@ -750,7 +741,6 @@
*
*
*
*

*
t.after() is called if test body throws (*ms)
Expand Down
5 changes: 1 addition & 4 deletions test/fixtures/test-runner/output/junit_reporter.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,7 @@ Error [ERR_TEST_FAILURE]: thrown from subtest sync throw fails at first
</testcase>
<testcase name="sync throw fails at second" time="*" classname="test" failure="thrown from subtest sync throw fails at second">
<failure type="testCodeFailure" message="thrown from subtest sync throw fails at second">
Error [ERR_TEST_FAILURE]: thrown from subtest sync throw fails at second
* {
[Error [ERR_TEST_FAILURE]: thrown from subtest sync throw fails at second] {
code: 'ERR_TEST_FAILURE',
failureType: 'testCodeFailure',
cause: Error: thrown from subtest sync throw fails at second
Expand All @@ -362,8 +361,6 @@ Error [ERR_TEST_FAILURE]: thrown from subtest sync throw fails at second
*
*
*
*
*
}
</failure>
</testcase>
Expand Down
2 changes: 0 additions & 2 deletions test/fixtures/test-runner/output/output.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,6 @@ not ok 51 - custom inspect symbol that throws fail
*
*
*
*
*
...
1..2
not ok 52 - subtest sync throw fails
Expand Down
2 changes: 0 additions & 2 deletions test/fixtures/test-runner/output/output_cli.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,6 @@ not ok 51 - custom inspect symbol that throws fail
*
*
*
*
*
...
1..2
not ok 52 - subtest sync throw fails
Expand Down
4 changes: 0 additions & 4 deletions test/fixtures/test-runner/output/spec_reporter.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,6 @@
*
*
*
*
*

subtest sync throw fails (*ms)
timed out async test (*ms)
Expand Down Expand Up @@ -495,8 +493,6 @@
*
*
*
*
*

*
timed out async test (*ms)
Expand Down
4 changes: 0 additions & 4 deletions test/fixtures/test-runner/output/spec_reporter_cli.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,6 @@
*
*
*
*
*

subtest sync throw fails (*ms)
timed out async test (*ms)
Expand Down Expand Up @@ -498,8 +496,6 @@
*
*
*
*
*

*
timed out async test (*ms)
Expand Down
14 changes: 8 additions & 6 deletions test/parallel/test-runner-module-mocking.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,13 +448,15 @@ test('mocks are automatically restored', async (t) => {
assert.strictEqual(mocked.fn(), 43);
});

const cjsMock = require(cjsFixture);
const esmMock = await import(esmFixture);
t.test('checks original behavior', async () => {
const cjsMock = require(cjsFixture);
const esmMock = await import(esmFixture);

assert.strictEqual(cjsMock.string, 'original cjs string');
assert.strictEqual(cjsMock.fn, undefined);
assert.strictEqual(esmMock.string, 'original esm string');
assert.strictEqual(esmMock.fn, undefined);
assert.strictEqual(cjsMock.string, 'original cjs string');
assert.strictEqual(cjsMock.fn, undefined);
assert.strictEqual(esmMock.string, 'original esm string');
assert.strictEqual(esmMock.fn, undefined);
});
});

test('mocks can be restored independently', async (t) => {
Expand Down

0 comments on commit 3788e00

Please sign in to comment.