From 7e68fb90447a63640041f0c6b7639edea9a30dc2 Mon Sep 17 00:00:00 2001 From: Jason Palmer Date: Wed, 27 Mar 2019 10:28:32 -0400 Subject: [PATCH 1/6] Do not retry test if beforeAll fails --- e2e/__tests__/testRetries.test.ts | 31 +++++++++++++++++++++++ e2e/test-retries/beforeAllFailure.test.js | 19 ++++++++++++++ packages/jest-circus/src/run.ts | 7 ++++- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 e2e/test-retries/beforeAllFailure.test.js diff --git a/e2e/__tests__/testRetries.test.ts b/e2e/__tests__/testRetries.test.ts index 6ae9ff75b2d7..3516c01b024c 100644 --- a/e2e/__tests__/testRetries.test.ts +++ b/e2e/__tests__/testRetries.test.ts @@ -92,4 +92,35 @@ describe('Test Retries', () => { expect(jsonResult.numPendingTests).toBe(0); expect(jsonResult.testResults[0].testResults[0].invocations).toBe(1); }); + + it('tests are not retried if beforeAll hook failure occurs', () => { + let jsonResult; + + const reporterConfig = { + reporters: [ + ['/reporters/RetryReporter.js', {output: outputFilePath}], + ], + }; + + runJest('test-retries', [ + '--config', + JSON.stringify(reporterConfig), + 'beforeAllFailure.test.js', + ]); + + const testOutput = fs.readFileSync(outputFilePath, 'utf8'); + + try { + jsonResult = JSON.parse(testOutput); + } catch (err) { + throw new Error( + `Can't parse the JSON result from ${outputFileName}, ${err.toString()}`, + ); + } + + expect(jsonResult.numPassedTests).toBe(0); + expect(jsonResult.numFailedTests).toBe(1); + expect(jsonResult.numPendingTests).toBe(0); + expect(jsonResult.testResults[0].testResults[0].invocations).toBe(1); + }); }); diff --git a/e2e/test-retries/beforeAllFailure.test.js b/e2e/test-retries/beforeAllFailure.test.js new file mode 100644 index 000000000000..c5de9ad624f0 --- /dev/null +++ b/e2e/test-retries/beforeAllFailure.test.js @@ -0,0 +1,19 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +jest.retryTimes(3); + +describe('beforeAll Failure Suite', () => { + beforeAll(async () => { + throw new Error('whoops'); + }); + + it('should not be invoked', () => { + throw new Error('should not be invoked'); + }); +}); diff --git a/packages/jest-circus/src/run.ts b/packages/jest-circus/src/run.ts index 04d5b8459b8d..a3e52060ea1f 100644 --- a/packages/jest-circus/src/run.ts +++ b/packages/jest-circus/src/run.ts @@ -48,9 +48,14 @@ const _runTestsForDescribeBlock = async (describeBlock: DescribeBlock) => { const deferredRetryTests = []; for (const test of describeBlock.tests) { + const isErrorsBeforeTestRun = test.errors.length > 0; await _runTest(test); - if (retryTimes > 0 && test.errors.length > 0) { + if ( + isErrorsBeforeTestRun === false && + retryTimes > 0 && + test.errors.length > 0 + ) { deferredRetryTests.push(test); } } From f5c029fc67975040ec6320f65508453df7494b31 Mon Sep 17 00:00:00 2001 From: Jason Palmer Date: Wed, 27 Mar 2019 10:43:22 -0400 Subject: [PATCH 2/6] Amend CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91a342f13fde..c6a0caa65283 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Fixes +- `[jest-circus]` Fix test retries with beforeAll/beforeEach failures ([#8227](https://github.com/facebook/jest/pull/8227)) - `[expect]` Fix circular references in iterable equality ([#8160](https://github.com/facebook/jest/pull/8160)) - `[jest-changed-files]` Change method of obtaining git root ([#8052](https://github.com/facebook/jest/pull/8052)) - `[jest-each]` Fix test function type ([#8145](https://github.com/facebook/jest/pull/8145)) From f164bb5e4d28059a3867b3ce41c12a67e8df1730 Mon Sep 17 00:00:00 2001 From: Jason Palmer Date: Wed, 27 Mar 2019 10:53:22 -0400 Subject: [PATCH 3/6] Update variable name for test retry logic --- packages/jest-circus/src/run.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/jest-circus/src/run.ts b/packages/jest-circus/src/run.ts index a3e52060ea1f..fcff37cd826a 100644 --- a/packages/jest-circus/src/run.ts +++ b/packages/jest-circus/src/run.ts @@ -48,11 +48,11 @@ const _runTestsForDescribeBlock = async (describeBlock: DescribeBlock) => { const deferredRetryTests = []; for (const test of describeBlock.tests) { - const isErrorsBeforeTestRun = test.errors.length > 0; + const hasErrorsBeforeTestRun = test.errors.length > 0; await _runTest(test); if ( - isErrorsBeforeTestRun === false && + hasErrorsBeforeTestRun === false && retryTimes > 0 && test.errors.length > 0 ) { From 20e9bed6122a7507b695feec72d3a76a6d7d9f78 Mon Sep 17 00:00:00 2001 From: Jason Palmer Date: Wed, 27 Mar 2019 11:26:13 -0400 Subject: [PATCH 4/6] Catch beforeAll error in e2e test suite --- e2e/__tests__/testRetries.test.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/e2e/__tests__/testRetries.test.ts b/e2e/__tests__/testRetries.test.ts index 3516c01b024c..06844c70cbcb 100644 --- a/e2e/__tests__/testRetries.test.ts +++ b/e2e/__tests__/testRetries.test.ts @@ -102,11 +102,13 @@ describe('Test Retries', () => { ], }; - runJest('test-retries', [ - '--config', - JSON.stringify(reporterConfig), - 'beforeAllFailure.test.js', - ]); + try { + runJest('test-retries', [ + '--config', + JSON.stringify(reporterConfig), + 'beforeAllFailure.test.js', + ]); + } catch (err) {} const testOutput = fs.readFileSync(outputFilePath, 'utf8'); From 6d2e6811ff084bc43c12a77cc9fdf8ed843b58b3 Mon Sep 17 00:00:00 2001 From: Jason Palmer Date: Wed, 27 Mar 2019 13:25:38 -0400 Subject: [PATCH 5/6] Fix test retries e2e test --- e2e/__tests__/testRetries.test.ts | 12 +++++------- e2e/test-retries/beforeAllFailure.test.js | 19 ------------------- 2 files changed, 5 insertions(+), 26 deletions(-) delete mode 100644 e2e/test-retries/beforeAllFailure.test.js diff --git a/e2e/__tests__/testRetries.test.ts b/e2e/__tests__/testRetries.test.ts index 06844c70cbcb..3516c01b024c 100644 --- a/e2e/__tests__/testRetries.test.ts +++ b/e2e/__tests__/testRetries.test.ts @@ -102,13 +102,11 @@ describe('Test Retries', () => { ], }; - try { - runJest('test-retries', [ - '--config', - JSON.stringify(reporterConfig), - 'beforeAllFailure.test.js', - ]); - } catch (err) {} + runJest('test-retries', [ + '--config', + JSON.stringify(reporterConfig), + 'beforeAllFailure.test.js', + ]); const testOutput = fs.readFileSync(outputFilePath, 'utf8'); diff --git a/e2e/test-retries/beforeAllFailure.test.js b/e2e/test-retries/beforeAllFailure.test.js deleted file mode 100644 index c5de9ad624f0..000000000000 --- a/e2e/test-retries/beforeAllFailure.test.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ -'use strict'; - -jest.retryTimes(3); - -describe('beforeAll Failure Suite', () => { - beforeAll(async () => { - throw new Error('whoops'); - }); - - it('should not be invoked', () => { - throw new Error('should not be invoked'); - }); -}); From 95d1e804deb4ef87ad2d30a64c0a69be04613b7e Mon Sep 17 00:00:00 2001 From: Jason Palmer Date: Wed, 27 Mar 2019 15:39:32 -0400 Subject: [PATCH 6/6] Add missing file for retry beforeAll failure test --- .../__tests__/beforeAllFailure.test.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 e2e/test-retries/__tests__/beforeAllFailure.test.js diff --git a/e2e/test-retries/__tests__/beforeAllFailure.test.js b/e2e/test-retries/__tests__/beforeAllFailure.test.js new file mode 100644 index 000000000000..915ee923a29d --- /dev/null +++ b/e2e/test-retries/__tests__/beforeAllFailure.test.js @@ -0,0 +1,17 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +jest.retryTimes(3); + +beforeAll(() => { + throw new Error('Failure in beforeAll'); +}); + +it('should not be retried because hook failure occurred', () => { + throw new Error('should not be invoked'); +});