Skip to content

Conversation

hainenber
Copy link
Contributor

@hainenber hainenber commented Oct 7, 2025

Summary

Closes #15588

collectCoverage to be toggled on-off at project level would be pretty handy for folks in monorepo. To implement this, collectCoverage's default value for projects has to be undefined unless specified otherwise.

This only affects --showConfig CLI option as JSON spec doesn't allow undefined value to be printed out so the result will miss collectCoverage value.

One caveat from this approach is the folks specifying collectCoverage: undefined for a project would not see desired result of filtering coverage statistics for that particular project but fortunately, the accepted value type in the doc is Boolean so I suspect people will realize the issue and use collectCoverage: true | false per doc.

Test plan

  • Green CI
  • UAT passed by affected user in linked GH issue.

Copy link

netlify bot commented Oct 7, 2025

Deploy Preview for jestjs ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit d533273
🔍 Latest deploy log https://app.netlify.com/projects/jestjs/deploys/68e9de63a82c3d0008bd899b
😎 Deploy Preview https://deploy-preview-15854--jestjs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Signed-off-by: hainenber <[email protected]>
Copy link

pkg-pr-new bot commented Oct 7, 2025

Open in StackBlitz

babel-jest

npm i https://pkg.pr.new/babel-jest@15854

babel-plugin-jest-hoist

npm i https://pkg.pr.new/babel-plugin-jest-hoist@15854

babel-preset-jest

npm i https://pkg.pr.new/babel-preset-jest@15854

create-jest

npm i https://pkg.pr.new/create-jest@15854

@jest/diff-sequences

npm i https://pkg.pr.new/@jest/diff-sequences@15854

expect

npm i https://pkg.pr.new/expect@15854

@jest/expect-utils

npm i https://pkg.pr.new/@jest/expect-utils@15854

jest

npm i https://pkg.pr.new/jest@15854

jest-changed-files

npm i https://pkg.pr.new/jest-changed-files@15854

jest-circus

npm i https://pkg.pr.new/jest-circus@15854

jest-cli

npm i https://pkg.pr.new/jest-cli@15854

jest-config

npm i https://pkg.pr.new/jest-config@15854

@jest/console

npm i https://pkg.pr.new/@jest/console@15854

@jest/core

npm i https://pkg.pr.new/@jest/core@15854

@jest/create-cache-key-function

npm i https://pkg.pr.new/@jest/create-cache-key-function@15854

jest-diff

npm i https://pkg.pr.new/jest-diff@15854

jest-docblock

npm i https://pkg.pr.new/jest-docblock@15854

jest-each

npm i https://pkg.pr.new/jest-each@15854

@jest/environment

npm i https://pkg.pr.new/@jest/environment@15854

jest-environment-jsdom

npm i https://pkg.pr.new/jest-environment-jsdom@15854

@jest/environment-jsdom-abstract

npm i https://pkg.pr.new/@jest/environment-jsdom-abstract@15854

jest-environment-node

npm i https://pkg.pr.new/jest-environment-node@15854

@jest/expect

npm i https://pkg.pr.new/@jest/expect@15854

@jest/fake-timers

npm i https://pkg.pr.new/@jest/fake-timers@15854

@jest/get-type

npm i https://pkg.pr.new/@jest/get-type@15854

@jest/globals

npm i https://pkg.pr.new/@jest/globals@15854

jest-haste-map

npm i https://pkg.pr.new/jest-haste-map@15854

jest-jasmine2

npm i https://pkg.pr.new/jest-jasmine2@15854

jest-leak-detector

npm i https://pkg.pr.new/jest-leak-detector@15854

jest-matcher-utils

npm i https://pkg.pr.new/jest-matcher-utils@15854

jest-message-util

npm i https://pkg.pr.new/jest-message-util@15854

jest-mock

npm i https://pkg.pr.new/jest-mock@15854

@jest/pattern

npm i https://pkg.pr.new/@jest/pattern@15854

jest-phabricator

npm i https://pkg.pr.new/jest-phabricator@15854

jest-regex-util

npm i https://pkg.pr.new/jest-regex-util@15854

@jest/reporters

npm i https://pkg.pr.new/@jest/reporters@15854

jest-resolve

npm i https://pkg.pr.new/jest-resolve@15854

jest-resolve-dependencies

npm i https://pkg.pr.new/jest-resolve-dependencies@15854

jest-runner

npm i https://pkg.pr.new/jest-runner@15854

jest-runtime

npm i https://pkg.pr.new/jest-runtime@15854

@jest/schemas

npm i https://pkg.pr.new/@jest/schemas@15854

jest-snapshot

npm i https://pkg.pr.new/jest-snapshot@15854

@jest/snapshot-utils

npm i https://pkg.pr.new/@jest/snapshot-utils@15854

@jest/source-map

npm i https://pkg.pr.new/@jest/source-map@15854

@jest/test-result

npm i https://pkg.pr.new/@jest/test-result@15854

@jest/test-sequencer

npm i https://pkg.pr.new/@jest/test-sequencer@15854

@jest/transform

npm i https://pkg.pr.new/@jest/transform@15854

@jest/types

npm i https://pkg.pr.new/@jest/types@15854

jest-util

npm i https://pkg.pr.new/jest-util@15854

jest-validate

npm i https://pkg.pr.new/jest-validate@15854

jest-watcher

npm i https://pkg.pr.new/jest-watcher@15854

jest-worker

npm i https://pkg.pr.new/jest-worker@15854

pretty-format

npm i https://pkg.pr.new/pretty-format@15854

commit: d533273

Copy link
Contributor

@ahnpnl ahnpnl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested the current behavior of 30.2.0 withcollectCoverage option. Here are what I found.

Given a config

export default {
  collectCoverage: true,
  projects: [
    {
      displayName: 'Package 1',
      rootDir: '<rootDir>/packages/package-1',
      testMatch: ['<rootDir>/test-e2e/**/*.e2e.js'],
    },
    {
      displayName: 'Package 2',
      rootDir: '<rootDir>/packages/package-2',
      testMatch: ['<rootDir>/test-e2e/**/*.e2e.js'],
    },
    {
      displayName: 'Package 3',
      rootDir: '<rootDir>/packages/package-3',
      testMatch: ['<rootDir>/test-e2e/**/*.e2e.js'],
    },
  ],
};
  • When having global collectCoverage: true, the collectCoverage value per project will be always set to false
  • When setting a collectCoverage: false for a project which means overriding the global level. This overriding value is correctly set for config argument of shouldInstrument function.

In summary

  • Solving the warning issue in #15588 only requires the change in jest-types, test-utils and jest-config/src/index.ts
  • To make the overriding value of collectCoverage works, it requires a change here
    await runtime.collectV8Coverage();

The condition collectV8Coverage currently takes value from

const collectV8Coverage =
which never uses the overriding value of project

@hainenber
Copy link
Contributor Author

Thanks @ahnpnl for the review! That would help resolving one of the pain point of changing collectCoverage type but I wonder if the proposed change can work with babel coverage provider too as well 🤔

@ahnpnl
Copy link
Contributor

ahnpnl commented Oct 11, 2025

The original issue #15588 uses provider v8 so I can only propose the change for v8. I've also checked for Babel provider. It has exactly same issue like v8. However, Idk where collecting coverage is called when using Babel. I can only find in jest-runtime where collecting v8 coverage is called.

Usually, jest-runtime decides whether to collect coverage based on config and jest-transform will ensure the codes are instrumented properly to collect coverage.

I hope these information will help you further for your investigation 👍

@hainenber
Copy link
Contributor Author

Thank you for your effort. I'll go back to the lab for this one.

@hainenber hainenber marked this pull request as draft October 11, 2025 13:45
@hainenber
Copy link
Contributor Author

I've re-examined both approach and unfortunately with default collectCoverage value at project level to be false, it's nigh impossible to distinguish between user-specific falsy value and default falsy value, except for its type.

I suppose we have to compromise by letting collectCoverage to be optional for a clear separation of 2 said factions.

@hainenber hainenber marked this pull request as ready for review October 11, 2025 15:21
@ahnpnl
Copy link
Contributor

ahnpnl commented Oct 11, 2025

The condition collectV8Coverage currently takes value from

const collectV8Coverage =
which never uses the overriding value of project

did you make this change to make v8 working correctly first? I think this one we should have

Have you checked where Babel coverage is called?

@hainenber
Copy link
Contributor Author

Yes, I've made changes to collectCoverage value to take the overridden value and limit only for v8 coverage provider

Changes in jest repo

  • Allow project-level collectCoverage to override global one
image
  • Revert changes in shouldInstrument to be on par with current Jest version
image

Result in test repo with jest built from above change

image

Have you checked where Babel coverage is called?

This is where I think the Babel coverage gets called after transformed by Babel.

@ahnpnl
Copy link
Contributor

ahnpnl commented Oct 11, 2025

I've re-examined both approach and unfortunately with default collectCoverage value at project level to be false, it's nigh impossible to distinguish between user-specific falsy value and default falsy value, except for its type.

I suppose we have to compromise by letting collectCoverage to be optional for a clear separation of 2 said factions.

I got this now. Indeed if we make collectCoverage as a mandatory prop for ProjectConfig, it’s impossible to tell if users disable/enable on purpose for projects. I think optional is the only way

@ahnpnl
Copy link
Contributor

ahnpnl commented Oct 12, 2025

I think we just need to adjust https://github.com/jestjs/jest/blob/main/e2e/__tests__/coverageReport.test.ts to reflect this change and all will be good 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Cannot specify unique test coverage per project

2 participants