From 008f95d06af03656791a3844ae055545a0c10802 Mon Sep 17 00:00:00 2001 From: Colin Ihrig Date: Thu, 27 Oct 2022 04:27:35 -0400 Subject: [PATCH] test_runner: call {before,after}Each() on suites Prior to this commit, beforeEach() and afterEach() hooks were not called on test suites (describe()). This commit addresses that. Fixes: https://github.com/nodejs/node/issues/45028 PR-URL: https://github.com/nodejs/node/pull/45161 Reviewed-By: Moshe Atlow Reviewed-By: Yagiz Nizipli Reviewed-By: James M Snell --- lib/internal/test_runner/test.js | 11 +++++ test/message/test_runner_hooks.js | 2 + test/message/test_runner_test_name_pattern.js | 47 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 test/message/test_runner_test_name_pattern.js diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index f02c173bff35eb..821961daed5cf7 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -706,13 +706,24 @@ class Suite extends Test { const hookArgs = this.getRunArgs(); + + if (this.parent?.hooks.beforeEach.length > 0) { + await this.parent[kRunHook]('beforeEach', hookArgs); + } + await this[kRunHook]('before', hookArgs); + const stopPromise = stopTest(this.timeout, this.signal); const subtests = this.skipped || this.error ? [] : this.subtests; const promise = SafePromiseAll(subtests, (subtests) => subtests.start()); await SafePromiseRace([promise, stopPromise]); await this[kRunHook]('after', hookArgs); + + if (this.parent?.hooks.afterEach.length > 0) { + await this.parent[kRunHook]('afterEach', hookArgs); + } + this.pass(); } catch (err) { if (isTestFailureError(err)) { diff --git a/test/message/test_runner_hooks.js b/test/message/test_runner_hooks.js index 2c3526ae510e3f..4820b01470d0fe 100644 --- a/test/message/test_runner_hooks.js +++ b/test/message/test_runner_hooks.js @@ -15,10 +15,12 @@ describe('describe hooks', () => { 'before describe hooks', 'beforeEach 1', '1', 'afterEach 1', 'beforeEach 2', '2', 'afterEach 2', + 'beforeEach nested', 'before nested', 'beforeEach nested 1', 'nested 1', 'afterEach nested 1', 'beforeEach nested 2', 'nested 2', 'afterEach nested 2', 'after nested', + 'afterEach nested', 'after describe hooks', ]); }); diff --git a/test/message/test_runner_test_name_pattern.js b/test/message/test_runner_test_name_pattern.js new file mode 100644 index 00000000000000..86bc45d7d4c85d --- /dev/null +++ b/test/message/test_runner_test_name_pattern.js @@ -0,0 +1,47 @@ +// Flags: --no-warnings --test-name-pattern=enabled --test-name-pattern=/pattern/i +'use strict'; +const common = require('../common'); +const { + after, + afterEach, + before, + beforeEach, + describe, + it, + test, +} = require('node:test'); + +test('top level test disabled', common.mustNotCall()); +test('top level skipped test disabled', { skip: true }, common.mustNotCall()); +test('top level skipped test enabled', { skip: true }, common.mustNotCall()); +it('top level it enabled', common.mustCall()); +it('top level it disabled', common.mustNotCall()); +it.skip('top level skipped it disabled', common.mustNotCall()); +it.skip('top level skipped it enabled', common.mustNotCall()); +describe('top level describe disabled', common.mustNotCall()); +describe.skip('top level skipped describe disabled', common.mustNotCall()); +describe.skip('top level skipped describe enabled', common.mustNotCall()); +test('top level runs because name includes PaTtErN', common.mustCall()); + +test('top level test enabled', common.mustCall(async (t) => { + t.beforeEach(common.mustCall()); + t.afterEach(common.mustCall()); + await t.test( + 'nested test runs because name includes PATTERN', + common.mustCall() + ); +})); + +describe('top level describe enabled', () => { + before(common.mustCall()); + beforeEach(common.mustCall(4)); + afterEach(common.mustCall(4)); + after(common.mustCall()); + + it('nested it disabled', common.mustNotCall()); + it('nested it enabled', common.mustCall()); + describe('nested describe disabled', common.mustNotCall()); + describe('nested describe enabled', common.mustCall(() => { + it('is enabled', common.mustCall()); + })); +});