This was copied over from #15358, opened in Oct 25, 2024, but over the past month went stale. It is still an issue in the latest version of Jest (Jul 2026). An MR was made in #16014 but it seems there hasn't been much movement on this.
Version
29.7.0, also tested in Jest 30.4.2.
Steps to reproduce
- Clone my repo https://github.com/tbossi/jest-bug-coverage-per-project
The repo contains two folders coverage-global and coverage-per-project. They are the same codebase with the exact same code but different Jest configuration.
- In each of those folders run
npm install then npm run test:coverage.
- You can see the files included in coverage report are different depending on which of the two main folder you look at.
- Additionally, enter in any of the packages (for example
pack1) again in both folders coverage-global and coverage-per-project. Then run npm run test:coverage for that single package.
- You can see the files included in these coverage report are different.
Expected behavior
The files without tests (pack1/file-without-test-1.js and pack2/file-without-test-2.js) should always be present in the coverage report if collectCoverageFrom is set on each package (both when running jest from root and from each individual package).
Actual behavior
The files without tests (pack1/file-without-test-1.js and pack2/file-without-test-2.js) are present in the coverage report only if:
- coverage is configured globally (folder
coverage-global) and jest --coverage is run from the root package.json
- coverage is configured per project (folder
coverage-per-project) and jest --coverage is run from each individual package of the workspace
Additional context
The project shown in the repo is organized using npm workspaces. There is a global jest configuration file (jest.config.js) that maps workspaces to jest's projects setting.
Individual packages each have their own configuration file, and share a common preset (jest.preset.js).
In this context, I want jest --coverage to also show me files without tests in each package. For this reason I used the collectCoverageFrom setting. However, this setting combined with the projects one seems to have unexpected results.
When setting collectCoverageFrom in the root jest.config.js (as it is in folder coverage-global) the files without tests are visible only when jest is run from the root, and not for a single package. That is kind of expected, since the jest.config.js of a single package has no setting collectCoverageFrom even in the preset.
What is not expected, is the other case (in folder coverage-per-project), where collectCoverageFrom is set in the preset and therefore shared by the jest.config.js of each single package. In this situation, which by the way is my go to configuration when dealing with jest combined with workspaces, if you run jest for a single package then the coverage of that package is correct. But if you run jest from the root then the files without coverage are missing.
Also note that having collectCoverageFrom in a preset is just to simplify the problem, but each individual package could also have its own collectCoverageFrom with different values.
I also did a bit of research on my own to find the root cause, and it seems to boil down to the method _addUntestedFiles of CoverageReporter. In the for loop there is a call to context.hasteFS.matchFilesWithGlob passing the global config, but there is no call to the same function passing the config of the current context under iteration.
Adding that missing piece seems to solve the issue, but I'm not sure if it's the right way to fix it.
Environment
System:
OS: Windows 11 10.0.22631
CPU: (12) x64 Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
Binaries:
Node: 20.13.0 - ~\AppData\Local\nvs\default\node.EXE
npm: 10.5.2 - ~\AppData\Local\nvs\default\npm.CMD
npmPackages:
jest: ^29.7.0 => 29.7.0
This was copied over from #15358, opened in Oct 25, 2024, but over the past month went stale. It is still an issue in the latest version of Jest (Jul 2026). An MR was made in #16014 but it seems there hasn't been much movement on this.
Version
29.7.0, also tested in Jest 30.4.2.
Steps to reproduce
The repo contains two folders
coverage-globalandcoverage-per-project. They are the same codebase with the exact same code but different Jest configuration.npm installthennpm run test:coverage.pack1) again in both folderscoverage-globalandcoverage-per-project. Then runnpm run test:coveragefor that single package.Expected behavior
The files without tests (
pack1/file-without-test-1.jsandpack2/file-without-test-2.js) should always be present in the coverage report ifcollectCoverageFromis set on each package (both when running jest from root and from each individual package).Actual behavior
The files without tests (
pack1/file-without-test-1.jsandpack2/file-without-test-2.js) are present in the coverage report only if:coverage-global) andjest --coverageis run from the rootpackage.jsoncoverage-per-project) andjest --coverageis run from each individual package of the workspaceAdditional context
The project shown in the repo is organized using npm workspaces. There is a global jest configuration file (
jest.config.js) that maps workspaces to jest'sprojectssetting.Individual packages each have their own configuration file, and share a common preset (
jest.preset.js).In this context, I want
jest --coverageto also show me files without tests in each package. For this reason I used thecollectCoverageFromsetting. However, this setting combined with theprojectsone seems to have unexpected results.When setting
collectCoverageFromin the rootjest.config.js(as it is in foldercoverage-global) the files without tests are visible only when jest is run from the root, and not for a single package. That is kind of expected, since thejest.config.jsof a single package has no settingcollectCoverageFromeven in the preset.What is not expected, is the other case (in folder
coverage-per-project), wherecollectCoverageFromis set in the preset and therefore shared by thejest.config.jsof each single package. In this situation, which by the way is my go to configuration when dealing with jest combined with workspaces, if you run jest for a single package then the coverage of that package is correct. But if you run jest from the root then the files without coverage are missing.Also note that having
collectCoverageFromin a preset is just to simplify the problem, but each individual package could also have its owncollectCoverageFromwith different values.I also did a bit of research on my own to find the root cause, and it seems to boil down to the method
_addUntestedFilesofCoverageReporter. In the for loop there is a call tocontext.hasteFS.matchFilesWithGlobpassing the global config, but there is no call to the same function passing the config of the current context under iteration.Adding that missing piece seems to solve the issue, but I'm not sure if it's the right way to fix it.
Environment