diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b63187776f8..309e3d342619 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Fixes - `[jest-config]` Handle frozen config object ([#14054](https://github.com/facebook/jest/pull/14054)) +- `[jest-core]` Always use workers in watch mode to avoid crashes ([#14059](https://github.com/facebook/jest/pull/14059)). - `[jest-environment-jsdom, jest-environment-node]` Fix assignment of `customExportConditions` via `testEnvironmentOptions` when custom env subclass defines a default value ([#13989](https://github.com/facebook/jest/pull/13989)) - `[jest-matcher-utils]` Fix copying value of inherited getters ([#14007](https://github.com/facebook/jest/pull/14007)) - `[jest-mock]` Tweak typings to allow `jest.replaceProperty()` replace methods ([#14008](https://github.com/facebook/jest/pull/14008)) diff --git a/packages/jest-core/src/__tests__/testSchedulerHelper.test.js b/packages/jest-core/src/__tests__/testSchedulerHelper.test.js index dc5cc6620bda..d4fbc2756750 100644 --- a/packages/jest-core/src/__tests__/testSchedulerHelper.test.js +++ b/packages/jest-core/src/__tests__/testSchedulerHelper.test.js @@ -24,8 +24,8 @@ const getTestsMock = () => [getTestMock(), getTestMock()]; test.each` tests | timings | detectOpenHandles | maxWorkers | watch | workerIdleMemoryLimit | expectedResult - ${[getTestMock()]} | ${[500, 500]} | ${false} | ${undefined} | ${true} | ${undefined} | ${true} - ${getTestsMock()} | ${[2000, 500]} | ${false} | ${1} | ${true} | ${undefined} | ${true} + ${[getTestMock()]} | ${[500, 500]} | ${false} | ${undefined} | ${true} | ${undefined} | ${false} + ${getTestsMock()} | ${[2000, 500]} | ${false} | ${1} | ${true} | ${undefined} | ${false} ${getTestsMock()} | ${[2000, 500]} | ${false} | ${2} | ${true} | ${undefined} | ${false} ${[getTestMock()]} | ${[2000, 500]} | ${false} | ${undefined} | ${true} | ${undefined} | ${false} ${getTestMock()} | ${[500, 500]} | ${false} | ${undefined} | ${true} | ${undefined} | ${false} @@ -36,8 +36,8 @@ test.each` ${new Array(45)} | ${[500]} | ${false} | ${undefined} | ${false} | ${undefined} | ${false} ${getTestsMock()} | ${[2000, 500]} | ${false} | ${undefined} | ${false} | ${undefined} | ${false} ${getTestsMock()} | ${[2000, 500]} | ${true} | ${undefined} | ${false} | ${undefined} | ${true} - ${[getTestMock()]} | ${[500, 500]} | ${false} | ${undefined} | ${true} | ${'500MB'} | ${true} - ${getTestsMock()} | ${[2000, 500]} | ${false} | ${1} | ${true} | ${'500MB'} | ${true} + ${[getTestMock()]} | ${[500, 500]} | ${false} | ${undefined} | ${true} | ${'500MB'} | ${false} + ${getTestsMock()} | ${[2000, 500]} | ${false} | ${1} | ${true} | ${'500MB'} | ${false} ${getTestsMock()} | ${[2000, 500]} | ${false} | ${1} | ${false} | ${'500MB'} | ${false} ${[getTestMock()]} | ${[2000]} | ${false} | ${undefined} | ${false} | ${'500MB'} | ${false} ${getTestsMock()} | ${[500, 500]} | ${false} | ${undefined} | ${false} | ${'500MB'} | ${false} diff --git a/packages/jest-core/src/testSchedulerHelper.ts b/packages/jest-core/src/testSchedulerHelper.ts index 434e903e2118..6582415ac5d5 100644 --- a/packages/jest-core/src/testSchedulerHelper.ts +++ b/packages/jest-core/src/testSchedulerHelper.ts @@ -27,25 +27,26 @@ export function shouldRunInBand( } /* - * Run in band if we only have one test or one worker available, unless we - * are using the watch mode, in which case the TTY has to be responsive and - * we cannot schedule anything in the main thread. Same logic applies to - * watchAll. + * If we are using watch/watchAll mode, don't schedule anything in the main + * thread to keep the TTY responsive and to prevent watch mode crashes caused + * by leaks (improper test teardown). + */ + if (watch || watchAll) { + return false; + } + + /* + * Otherwise, run in band if we only have one test or one worker available. * Also, if we are confident from previous runs that the tests will finish * quickly we also run in band to reduce the overhead of spawning workers. * Finally, the user can provide the runInBand argument in the CLI to - * force running in band. - * https://github.com/facebook/jest/blob/700e0dadb85f5dc8ff5dac6c7e98956690049734/packages/jest-config/src/getMaxWorkers.js#L14-L17 + * force running in band, which sets maxWorkers to 1 here: + * https://github.com/facebook/jest/blob/d106643a8ee0ffa9c2f11c6bb2d12094e99135aa/packages/jest-config/src/getMaxWorkers.ts#L27-L28 */ - const isWatchMode = watch || watchAll; const areFastTests = timings.every(timing => timing < SLOW_TEST_TIME); const oneWorkerOrLess = maxWorkers <= 1; const oneTestOrLess = tests.length <= 1; - if (isWatchMode) { - return oneWorkerOrLess || (oneTestOrLess && areFastTests); - } - return ( // When specifying a memory limit, workers should be used !workerIdleMemoryLimit &&