Skip to content

Commit

Permalink
feat: add t.after() hook
Browse files Browse the repository at this point in the history
This commit adds an after() hook to the TestContext class. This
hook can be used to clean up after a test finishes.

PR-URL: nodejs/node#45792
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
(cherry picked from commit 215c5317d4837287fddb2e3b97872babd53183ac)
  • Loading branch information
cjihrig authored and MoLow committed Feb 2, 2023
1 parent b3b384e commit 71b659e
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,33 @@ test('top level test', async (t) => {
});
```

### `context.after([fn][, options])`

<!-- YAML
added: REPLACEME
-->

* `fn` {Function|AsyncFunction} The hook function. The first argument
to this function is a [`TestContext`][] object. If the hook uses callbacks,
the callback function is passed as the second argument. **Default:** A no-op
function.
* `options` {Object} Configuration options for the hook. The following
properties are supported:
* `signal` {AbortSignal} Allows aborting an in-progress hook.
* `timeout` {number} A number of milliseconds the hook will fail after.
If unspecified, subtests inherit this value from their parent.
**Default:** `Infinity`.

This function is used to create a hook that runs after the current test
finishes.

```js
test('top level test', async (t) => {
t.after((t) => t.diagnostic(`finished running ${t.name}`));
assert.ok('some relevant assertion here');
});
```

### `context.afterEach([, fn][, options])`

* `fn` {Function|AsyncFunction} The hook function. The first argument
Expand Down
7 changes: 6 additions & 1 deletion lib/internal/test_runner/test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// https://github.com/nodejs/node/blob/8302b0add01758713246117d3d0533cd212f160d/lib/internal/test_runner/test.js
// https://github.com/nodejs/node/blob/215c5317d4837287fddb2e3b97872babd53183ac/lib/internal/test_runner/test.js

'use strict'

Expand Down Expand Up @@ -140,6 +140,10 @@ class TestContext {
return subtest.start()
}

after (fn, options) {
this.#test.createHook('after', fn, options)
}

beforeEach (fn, options) {
this.#test.createHook('beforeEach', fn, options)
}
Expand Down Expand Up @@ -533,6 +537,7 @@ class Test extends AsyncResource {
return
}

await this.runHook('after', { args, ctx })
await afterEach()
this.pass()
} catch (err) {
Expand Down
10 changes: 8 additions & 2 deletions test/message/test_runner_hooks.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// https://github.com/nodejs/node/blob/3759935ee29d8042d917d3ceaa768521c14413ff/test/message/test_runner_hooks.js
// https://github.com/nodejs/node/blob/215c5317d4837287fddb2e3b97872babd53183ac/test/message/test_runner_hooks.js
// Flags: --no-warnings
'use strict'
const common = require('../common')
Expand Down Expand Up @@ -91,6 +91,8 @@ describe('afterEach throws and test fails', () => {

test('test hooks', async (t) => {
const testArr = []

t.after(common.mustCall((t) => testArr.push('after ' + t.name)))
t.beforeEach((t) => testArr.push('beforeEach ' + t.name))
t.afterEach((t) => testArr.push('afterEach ' + t.name))
await t.test('1', () => testArr.push('1'))
Expand All @@ -114,25 +116,29 @@ test('test hooks', async (t) => {
})

test('t.beforeEach throws', async (t) => {
t.after(common.mustCall())
t.beforeEach(() => { throw new Error('beforeEach') })
await t.test('1', () => {})
await t.test('2', () => {})
})

test('t.afterEach throws', async (t) => {
t.after(common.mustCall())
t.afterEach(() => { throw new Error('afterEach') })
await t.test('1', () => {})
await t.test('2', () => {})
})

test('afterEach when test fails', async (t) => {
t.after(common.mustCall())
t.afterEach(common.mustCall(2))
await t.test('1', () => { throw new Error('test') })
await t.test('2', () => {})
})

test('afterEach throws and test fails', async (t) => {
afterEach(() => { throw new Error('afterEach') })
t.after(common.mustCall())
t.afterEach(() => { throw new Error('afterEach') })
await t.test('1', () => { throw new Error('test') })
await t.test('2', () => {})
})

0 comments on commit 71b659e

Please sign in to comment.