GeezerVison is showing github.com — test_runner: avoid running twice tests in describe · nodejs/node@413493c
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: doc/api/test.md +9-5Lines changed: 9 additions & 5 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -767,7 +767,8 @@ changes: | 767 | 767 | to this function is a [`TestContext`][] object. If the test uses callbacks, | 768 | 768 | the callback function is passed as the second argument. **Default:** A no-op | 769 | 769 | function. | 770 | | -* Returns: {Promise} Resolved with `undefined` once the test completes. | | 770 | +* Returns: {Promise} Resolved with `undefined` once | | 771 | + the test completes, or immediately if the test runs within [`describe()`][]. | 771 | 772 |
| 772 | 773 | The `test()` function is the value imported from the `test` module. Each | 773 | 774 | invocation of this function results in reporting the test to the {TestsStream}. | @@ -776,10 +777,12 @@ The `TestContext` object passed to the `fn` argument can be used to perform | 776 | 777 | actions related to the current test. Examples include skipping the test, adding | 777 | 778 | additional diagnostic information, or creating subtests. | 778 | 779 |
| 779 | | -`test()` returns a `Promise` that resolves once the test completes. The return | 780 | | -value can usually be discarded for top level tests. However, the return value | 781 | | -from subtests should be used to prevent the parent test from finishing first | 782 | | -and cancelling the subtest as shown in the following example. | | 780 | +`test()` returns a `Promise` that resolves once the test completes. | | 781 | +if `test()` is called within a `describe()` block, it resolve immediately. | | 782 | +The return value can usually be discarded for top level tests. | | 783 | +However, the return value from subtests should be used to prevent the parent | | 784 | +test from finishing first and cancelling the subtest | | 785 | +as shown in the following example. | 783 | 786 |
| 784 | 787 | ```js | 785 | 788 | test('top level test', async (t) => { | @@ -1700,6 +1703,7 @@ added: v18.7.0 | 1700 | 1703 | [`context.diagnostic`]: #contextdiagnosticmessage | 1701 | 1704 | [`context.skip`]: #contextskipmessage | 1702 | 1705 | [`context.todo`]: #contexttodomessage | | 1706 | +[`describe()`]: #describename-options-fn | 1703 | 1707 | [`run()`]: #runoptions | 1704 | 1708 | [`test()`]: #testname-options-fn | 1705 | 1709 | [describe options]: #describename-options-fn | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/test_runner/harness.js +12-15Lines changed: 12 additions & 15 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | 'use strict'; | 2 | 2 | const { | 3 | 3 | ArrayPrototypeForEach, | | 4 | + PromiseResolve, | 4 | 5 | SafeMap, | 5 | 6 | } = primordials; | 6 | 7 | const { | @@ -185,31 +186,27 @@ async function startSubtest(subtest) { | 185 | 186 | await subtest.start(); | 186 | 187 | } | 187 | 188 |
| 188 | | -function test(name, options, fn) { | 189 | | - const parent = testResources.get(executionAsyncId()) || getGlobalRoot(); | 190 | | - const subtest = parent.createSubtest(Test, name, options, fn); | 191 | | - return startSubtest(subtest); | 192 | | -} | 193 | | - | 194 | | -function runInParentContext(Factory) { | | 189 | +function runInParentContext(Factory, addShorthands = true) { | 195 | 190 | function run(name, options, fn, overrides) { | 196 | 191 | const parent = testResources.get(executionAsyncId()) || getGlobalRoot(); | 197 | 192 | const subtest = parent.createSubtest(Factory, name, options, fn, overrides); | 198 | | - if (parent === getGlobalRoot()) { | 199 | | - startSubtest(subtest); | | 193 | + if (!(parent instanceof Suite)) { | | 194 | + return startSubtest(subtest); | 200 | 195 | } | | 196 | + return PromiseResolve(); | 201 | 197 | } | 202 | 198 |
| 203 | | - const cb = (name, options, fn) => { | 204 | | - run(name, options, fn); | 205 | | - }; | | 199 | + const test = (name, options, fn) => run(name, options, fn); | | 200 | + if (!addShorthands) { | | 201 | + return test; | | 202 | + } | 206 | 203 |
| 207 | 204 | ArrayPrototypeForEach(['skip', 'todo', 'only'], (keyword) => { | 208 | | - cb[keyword] = (name, options, fn) => { | | 205 | + test[keyword] = (name, options, fn) => { | 209 | 206 | run(name, options, fn, { [keyword]: true }); | 210 | 207 | }; | 211 | 208 | }); | 212 | | - return cb; | | 209 | + return test; | 213 | 210 | } | 214 | 211 |
| 215 | 212 | function hook(hook) { | @@ -221,7 +218,7 @@ function hook(hook) { | 221 | 218 |
| 222 | 219 | module.exports = { | 223 | 220 | createTestTree, | 224 | | - test, | | 221 | + test: runInParentContext(Test, false), | 225 | 222 | describe: runInParentContext(Suite), | 226 | 223 | it: runInParentContext(Test), | 227 | 224 | before: hook('before'), | |
Collapse file Copy file name to clipboardExpand all lines: test/message/test_runner_hooks.js +8-8Lines changed: 8 additions & 8 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -32,7 +32,7 @@ describe('describe hooks', () => { | 32 | 32 | }); | 33 | 33 |
| 34 | 34 | it('1', () => testArr.push('1')); | 35 | | - it('2', () => testArr.push('2')); | | 35 | + test('2', () => testArr.push('2')); | 36 | 36 |
| 37 | 37 | describe('nested', () => { | 38 | 38 | before(function() { | @@ -48,44 +48,44 @@ describe('describe hooks', () => { | 48 | 48 | testArr.push('afterEach ' + this.name); | 49 | 49 | }); | 50 | 50 | it('nested 1', () => testArr.push('nested 1')); | 51 | | - it('nested 2', () => testArr.push('nested 2')); | | 51 | + test('nested 2', () => testArr.push('nested 2')); | 52 | 52 | }); | 53 | 53 | }); | 54 | 54 |
| 55 | 55 | describe('before throws', () => { | 56 | 56 | before(() => { throw new Error('before'); }); | 57 | 57 | it('1', () => {}); | 58 | | - it('2', () => {}); | | 58 | + test('2', () => {}); | 59 | 59 | }); | 60 | 60 |
| 61 | 61 | describe('after throws', () => { | 62 | 62 | after(() => { throw new Error('after'); }); | 63 | 63 | it('1', () => {}); | 64 | | - it('2', () => {}); | | 64 | + test('2', () => {}); | 65 | 65 | }); | 66 | 66 |
| 67 | 67 | describe('beforeEach throws', () => { | 68 | 68 | beforeEach(() => { throw new Error('beforeEach'); }); | 69 | 69 | it('1', () => {}); | 70 | | - it('2', () => {}); | | 70 | + test('2', () => {}); | 71 | 71 | }); | 72 | 72 |
| 73 | 73 | describe('afterEach throws', () => { | 74 | 74 | afterEach(() => { throw new Error('afterEach'); }); | 75 | 75 | it('1', () => {}); | 76 | | - it('2', () => {}); | | 76 | + test('2', () => {}); | 77 | 77 | }); | 78 | 78 |
| 79 | 79 | describe('afterEach when test fails', () => { | 80 | 80 | afterEach(common.mustCall(2)); | 81 | 81 | it('1', () => { throw new Error('test'); }); | 82 | | - it('2', () => {}); | | 82 | + test('2', () => {}); | 83 | 83 | }); | 84 | 84 |
| 85 | 85 | describe('afterEach throws and test fails', () => { | 86 | 86 | afterEach(() => { throw new Error('afterEach'); }); | 87 | 87 | it('1', () => { throw new Error('test'); }); | 88 | | - it('2', () => {}); | | 88 | + test('2', () => {}); | 89 | 89 | }); | 90 | 90 |
| 91 | 91 | test('test hooks', async (t) => { | |
|