Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test_runner: add suite() #52127

Merged
merged 1 commit into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 69 additions & 37 deletions doc/api/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ test('top level test', async (t) => {
> between each subtest execution.

In this example, `await` is used to ensure that both subtests have completed.
This is necessary because parent tests do not wait for their subtests to
complete, unlike tests created with the `describe` and `it` syntax.
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.
Expand Down Expand Up @@ -162,12 +162,11 @@ test('skip() method with message', (t) => {
});
```

## `describe`/`it` syntax
## `describe()` and `it()` aliases

Running tests can also be done using `describe` to declare a suite
and `it` to declare a test.
A suite is used to organize and group related tests together.
`it` is a shorthand for [`test()`][].
Suites and tests can also be written using the `describe()` and `it()`
functions. [`describe()`][] is an alias for [`suite()`][], and [`it()`][] is an
alias for [`test()`][].

```js
describe('A thing', () => {
Expand All @@ -187,7 +186,7 @@ describe('A thing', () => {
});
```

`describe` and `it` are imported from the `node:test` module.
`describe()` and `it()` are imported from the `node:test` module.

```mjs
import { describe, it } from 'node:test';
Expand Down Expand Up @@ -1204,6 +1203,51 @@ run({ files: [path.resolve('./tests/test.js')] })
.pipe(process.stdout);
```

## `suite([name][, options][, fn])`

<!-- YAML
added: REPLACEME
-->

* `name` {string} The name of the suite, which is displayed when reporting test
results. **Default:** The `name` property of `fn`, or `'<anonymous>'` if `fn`
does not have a name.
* `options` {Object} Optional configuration options for the suite.
This supports the same options as `test([name][, options][, fn])`.
* `fn` {Function|AsyncFunction} The suite function declaring nested tests and
suites. The first argument to this function is a [`SuiteContext`][] object.
**Default:** A no-op function.
* Returns: {Promise} Immediately fulfilled with `undefined`.

The `suite()` function is imported from the `node:test` module.

## `suite.skip([name][, options][, fn])`

<!-- YAML
added: REPLACEME
-->

Shorthand for skipping a suite. This is the same as
[`suite([name], { skip: true }[, fn])`][suite options].

## `suite.todo([name][, options][, fn])`

<!-- YAML
added: REPLACEME
-->

Shorthand for marking a suite as `TODO`. This is the same as
[`suite([name], { todo: true }[, fn])`][suite options].

## `suite.only([name][, options][, fn])`

<!-- YAML
added: REPLACEME
-->

Shorthand for marking a suite as `only`. This is the same as
[`suite([name], { only: true }[, fn])`][suite options].

## `test([name][, options][, fn])`

<!-- YAML
Expand Down Expand Up @@ -1257,7 +1301,7 @@ changes:
the callback function is passed as the second argument. **Default:** A no-op
function.
* Returns: {Promise} Fulfilled with `undefined` once
the test completes, or immediately if the test runs within [`describe()`][].
the test completes, or immediately if the test runs within a suite.

The `test()` function is the value imported from the `test` module. Each
invocation of this function results in reporting the test to the {TestsStream}.
Expand All @@ -1267,7 +1311,7 @@ actions related to the current test. Examples include skipping the test, adding
additional diagnostic information, or creating subtests.

`test()` returns a `Promise` that fulfills once the test completes.
if `test()` is called within a `describe()` block, it fulfills immediately.
if `test()` is called within a suite, it fulfills immediately.
The return value can usually be discarded for top level tests.
However, the return value from subtests should be used to prevent the parent
test from finishing first and cancelling the subtest
Expand Down Expand Up @@ -1308,29 +1352,18 @@ same as [`test([name], { only: true }[, fn])`][it options].

## `describe([name][, options][, fn])`

* `name` {string} The name of the suite, which is displayed when reporting test
results. **Default:** The `name` property of `fn`, or `'<anonymous>'` if `fn`
does not have a name.
* `options` {Object} Configuration options for the suite.
supports the same options as `test([name][, options][, fn])`.
* `fn` {Function|AsyncFunction} The function under suite
declaring all subtests and subsuites.
The first argument to this function is a [`SuiteContext`][] object.
**Default:** A no-op function.
* Returns: {Promise} Immediately fulfilled with `undefined`.
Alias for [`suite()`][].

The `describe()` function imported from the `node:test` module. Each
invocation of this function results in the creation of a Subtest.
After invocation of top level `describe` functions,
all top level tests and suites will execute.
The `describe()` function is imported from the `node:test` module.

## `describe.skip([name][, options][, fn])`

Shorthand for skipping a suite, same as [`describe([name], { skip: true }[, fn])`][describe options].
Shorthand for skipping a suite. This is the same as
[`describe([name], { skip: true }[, fn])`][describe options].

## `describe.todo([name][, options][, fn])`

Shorthand for marking a suite as `TODO`, same as
Shorthand for marking a suite as `TODO`. This is the same as
[`describe([name], { todo: true }[, fn])`][describe options].

## `describe.only([name][, options][, fn])`
Expand All @@ -1341,7 +1374,7 @@ added:
- v18.15.0
-->

Shorthand for marking a suite as `only`, same as
Shorthand for marking a suite as `only`. This is the same as
[`describe([name], { only: true }[, fn])`][describe options].

## `it([name][, options][, fn])`
Expand All @@ -1358,7 +1391,7 @@ changes:
description: Calling `it()` is now equivalent to calling `test()`.
-->

Shorthand for [`test()`][].
Alias for [`test()`][].

The `it()` function is imported from the `node:test` module.

Expand Down Expand Up @@ -1402,7 +1435,7 @@ added:
If unspecified, subtests inherit this value from their parent.
**Default:** `Infinity`.

This function is used to create a hook running before running a suite.
This function creates a hook that runs before executing a suite.

```js
describe('tests', async () => {
Expand Down Expand Up @@ -1432,7 +1465,7 @@ added:
If unspecified, subtests inherit this value from their parent.
**Default:** `Infinity`.

This function is used to create a hook running after running a suite.
This function creates a hook that runs after executing a suite.

```js
describe('tests', async () => {
Expand Down Expand Up @@ -1465,8 +1498,7 @@ added:
If unspecified, subtests inherit this value from their parent.
**Default:** `Infinity`.

This function is used to create a hook running
before each subtest of the current suite.
This function creates a hook that runs before each test in the current suite.

```js
describe('tests', async () => {
Expand Down Expand Up @@ -1496,11 +1528,8 @@ added:
If unspecified, subtests inherit this value from their parent.
**Default:** `Infinity`.

This function is used to create a hook running
after each subtest of the current test.

**Note:** The `afterEach` hook is guaranteed to run after every test,
even if any of the tests fail.
This function creates a hook that runs after each test in the current suite.
The `afterEach()` hook is run even if the test fails.

```js
describe('tests', async () => {
Expand Down Expand Up @@ -3075,10 +3104,13 @@ Can be used to abort test subtasks when the test has been aborted.
[`context.todo`]: #contexttodomessage
[`describe()`]: #describename-options-fn
[`glob(7)`]: https://man7.org/linux/man-pages/man7/glob.7.html
[`it()`]: #itname-options-fn
[`run()`]: #runoptions
[`suite()`]: #suitename-options-fn
[`test()`]: #testname-options-fn
[describe options]: #describename-options-fn
[it options]: #testname-options-fn
[stream.compose]: stream.md#streamcomposestreams
[suite options]: #suitename-options-fn
[test reporters]: #test-reporters
[test runner execution model]: #test-runner-execution-model
3 changes: 1 addition & 2 deletions lib/internal/test_runner/harness.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,7 @@ function hook(hook) {
module.exports = {
createTestTree,
test: runInParentContext(Test),
describe: runInParentContext(Suite),
it: runInParentContext(Test),
suite: runInParentContext(Suite),
before: hook('before'),
after: hook('after'),
beforeEach: hook('beforeEach'),
Expand Down
7 changes: 4 additions & 3 deletions lib/test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';
const { ObjectAssign, ObjectDefineProperty } = primordials;
const { test, describe, it, before, after, beforeEach, afterEach } = require('internal/test_runner/harness');
const { test, suite, before, after, beforeEach, afterEach } = require('internal/test_runner/harness');
const { run } = require('internal/test_runner/runner');

module.exports = test;
Expand All @@ -9,9 +9,10 @@ ObjectAssign(module.exports, {
afterEach,
before,
beforeEach,
describe,
it,
describe: suite,
it: test,
run,
suite,
test,
});

Expand Down
8 changes: 8 additions & 0 deletions test/parallel/test-runner-aliases.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';
require('../common');
const { strictEqual } = require('node:assert');
const test = require('node:test');

strictEqual(test.test, test);
strictEqual(test.it, test);
strictEqual(test.describe, test.suite);
Loading