jest: runInBand + dynamic imports break in Jest 27.0.0-next.11
š Bug Report
Running jest in parallel works fine, but with runInBand
enabled, all tests with dynamic imports fail with the error Test environment has been torn down
Often, if I run a single test, the test will work the first time and then error on subsequent tests. Changing the imported file will fix the test on the next run, but then fail on the subsequent ones.
To reproduce
//foo.js
export default 'hello'
//faulty.test.js
test('test1', async () => {
const module = await import('./foo.js')
expect(module).toBeDefined()
})
Run the above test with --runInBand --watch
. Once finished, click enter to trigger another run.
Expected behavior
Test should pass on subsequent runs, but instead only the first test passes and subsequent runs break.
envinfo
Verified on: Windows, Mac, Ubuntu (Github action), WSL Node: 14 & 15 NPM: 6 & 7
System:
OS: Windows 10 10.0.19041
CPU: (16) x64 AMD Ryzen 7 1700 Eight-Core Processor
Binaries:
Node: 14.17.0 - ~\AppData\Local\Volta\tools\image\node\14.17.0\node.EXE
Yarn: 1.21.1 - C:\Program Files\Volta\yarn.EXE
npm: 6.14.13 - ~\AppData\Local\Volta\tools\image\npm\6.14.13\bin\npm.CMD
npmPackages:
jest: ^27.0.0-next.11 => 27.0.0-next.11
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 16
- Comments: 32 (7 by maintainers)
Commits related to this issue
- run only db jest tests https://github.com/facebook/jest/issues/11438 — committed to DarkPark/api by DarkPark 3 years ago
- Run CI on node 14, but skip unit tests until facebook/jest#11438 is solved — committed to graphql-editor/stucco-js by Dennor 3 years ago
- test: jestify runtime-plugin-import test and fix flaky test Migrated test from Tap to Jest. File Path: packages/cactus-test-cmd-api-server/src/test/typescript/integration/runtime-plugin-imports.test... — committed to Leeyoungone/cactus by awadhana 3 years ago
- test: jestify runtime-plugin-import test and fix flaky test Migrated test from Tap to Jest. File Path: packages/cactus-test-cmd-api-server/src/test/typescript/integration/runtime-plugin-imports.test... — committed to hyperledger/cacti by awadhana 3 years ago
- test: jestify runtime-plugin-import test and fix flaky test Migrated test from Tap to Jest. File Path: packages/cactus-test-cmd-api-server/src/test/typescript/integration/runtime-plugin-imports.test... — committed to zondervancalvez/cactus by awadhana 3 years ago
- fix: Use cosmiconfigSync to work around segfault in tests Consistently running into a segfault coming from Node as a result of cosmiconfig attempting to run a dynamic import on the listed .js config ... — committed to ryanwilsonperkin/unimported by ryanwilsonperkin 9 months ago
- Add support for alternative config files with cosmiconfig (#178) Fixes #118 Introduces `cosmiconfig` as requested in #118 in order to support loading the config from alternative file formats lik... — committed to smeijer/unimported by ryanwilsonperkin 9 months ago
I donāt think it has been fixed yet. I got this error with Node 17, 18 and 19.
Iām also facing the same issue with
--runInBand
and it seems like that node.js have fixed it in version 16.11.0, see my GitHub Actions run.Workaround is to disable
runInBand
in your project and setmaxWorkers
andmaxConcurrency
to value greater or equal test amount, for example in my repository I have maximum 7 tests per project that uses dynamic import, so Iāve set this values to 8 (and probably thatās why tests are pass on my local machine, I have 8 cores on laptop and 16 on desktop) As well Iāve increased timeout and magic happened! My CI is now green, links:@SimenB it seems like that for ESM we have to instantiate new worker per each test file to workaround this issue at least for thoose who use Node.js < 16.11.0
This is almost certainly https://github.com/nodejs/node/issues/36351 or https://github.com/nodejs/node/issues/33439 (either way itās further upstream: https://bugs.chromium.org/p/v8/issues/detail?id=10284)
Going one step further: by placing console logs within jest-runtime
loadEsmModule()
function and jest-environment-node constructor andteardown()
, I found out a mismatch in environment handling.Basically, each test file has its own Node environment: it is configured before running tests within the file, and tore down at the end. What happens is
Iāve tried to import all my modules dynamically, to use
isolateModule()
andresetModules()
, but I couldnāt find a way to force the second file using its own environment.Hi there. Iām also experiencing this issue, and made a stable reproduction repository here
As you can see, Iāve stripped down all my code to the minimum: a module (index.js) dynamically importing another one (internals.js).
As long as I had a single test file importing
index.js
, everything was fine. As soon as Iāve added another test file on the same guy, the issue happens.Iāve lost considerable time digging it, without finding any workaround nor root cause, but my gut feeling is that the jest-node-environment is tear down, then reused. Its VMcontext is gone, preventing further dynamic imports to work.
For jest users:
Try running jest --clearCache before running your actual tests (equals to disable jestās transform cache).
This may help in some situations.
If this works for you, you can turn off jestās cache ability in jest.config with cache: false.
https://github.com/nodejs/node/issues/35889#issuecomment-1521334188
On my tests, this issue is fixed on Node >=16.11 issue.zip <- Credits to @fwh1990 , I just simplified the example removing ts and other unrequired code
A workaround Iām using is to run each test file separately, rather than telling Jest to run everything in a dir tree. Itās kludgy, but until V8 fixes this, so that Node can fix it, so that Jest can work with it, not a lot of choice if you donāt want to run into caching issues:
With testing code that relies on dynamic imports:
with the operative dynamic import in Models:
But even then, this workaround probably still has pitfalls that Iāve simply not run into (yet).
Again, this is a bug in V8, there is nothing we can do except wait for Google to fix and release it, then Node to update their version of V8 and backport it to v12, v14 and v16