jestjs / jest

Delightful JavaScript Testing.
https://jestjs.io
MIT License
44.2k stars 6.46k forks source link

Code coverage is missing when using projects, if each project's rootDir is not set to the root rootDir's value #5417

Open jure opened 6 years ago

jure commented 6 years ago

Do you want to request a feature or report a bug?

A bug.

What is the current behavior?

When you're using Jest with projects and you want to collect coverage across them, following this advice https://github.com/facebook/jest/issues/4255#issuecomment-321939025 does not give you coverage. You still need to set each project's rootDir setting to the root root, e.g. "../" (https://github.com/adaniliuk/jest-projects-config-issue/blob/master/client/jest.config.js#L4).

If the current behavior is a bug, please provide the steps to reproduce and either a repl.it demo through https://repl.it/languages/jest or a minimal repository on GitHub that we can yarn install and yarn test.

You can see it here. https://github.com/jure/jest-projects-config-issue. The current result is:

Test Suites: 2 passed, 2 total
Tests:       4 passed, 4 total
Snapshots:   1 passed, 1 total
Time:        1.809s, estimated 2s
Ran all test suites in 2 projects.
----------|----------|----------|----------|----------|----------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
----------|----------|----------|----------|----------|----------------|
All files |  Unknown |  Unknown |  Unknown |  Unknown |                |
----------|----------|----------|----------|----------|----------------|

If you were to add rootDir ../../ to each project, and adjust the configs accordingly, it would work OK.

What is the expected behavior?

Configuring a global coverage config (e.g. here https://github.com/jure/jest-projects-config-issue/blob/master/jest.config.js#L6) should use the global rootDir (which is also the context of the config at that point), when matching files for instrumentation here: https://github.com/facebook/jest/blob/9afeb9c757e4b92dbf670e66545dce3df5c407c4/packages/jest-runtime/src/should_instrument.js#L59-L69.

As it is, the match is done against the relative path, where rootDir is the rootDir of each project, e.g.

relative filename:  server.js
filename:  /Users/juretriglav/src/config-issue-2/packages/server/server.js
rootDir:  /Users/juretriglav/src/config-issue-2/packages/server

This means that, for example, the global pattern 'packages/server/**/*.{js,jsx}' won't match.

Possible workarounds

  1. It's possible to specify global coverage patterns in their relative form, e.g. '*.js', but those are too generic and match too much compared to their specific alternatives.

  2. As mentioned above, one can specify rootDir to be the global rootDir in each package, and adjust all config accordingly. This seems like more of a hack than a workable solution.

Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.

Jest 22.1.4, Node.js 9.4.0, macOS 10.12.6

jure commented 6 years ago

The second workaround of setting rootDir actually messes with a bunch of other things (e.g. you need to be careful to specify exact testRegexes, otherwise it starts matching elsewhere, the .babelrc-based transforms stop working, etc.), so it's not really an option.

dioklecijan commented 6 years ago

Run jest with --showConfig and you will see that each project's rootDir is overwritten with the directory in which the config file resides. My workaround is to put one common jest.config.js in root dir. Something like:

let packages = getThePathsOfMyProjects(); // ['./packages/client', './packages/server' ..]

const projectConfigs = packages.map(packagePath => ({
  roots: [packagePath],
  rootDir: 'whatever I set it will be overwritten',
  testEnvironment: 'node',
  testMatch: ['**/test/**/*.js?(x)'],
  ...
}));

module.exports = {
  projects: projectConfigs,
  collectCoverageFrom: ['packages/**/*.{js,jsx}'],
  ...
};
jure commented 6 years ago

@dioklecijan I've tried this and can't get it to work for the life of me. If I put testMatch in the projects array, no tests are found matching no matter what pattern I try (it seems to use the default). Is this approach still working for you? Which version are you using?

eric-burel commented 3 years ago

I feel like there is something off with collectCoverageFrom and testMatch options. It seems to exclude tests automatically based on testMatch option, but when using a project, since you have multiple testMatch, tests are not removed from my test. It doesn't manage to "merge" all patterns.

j3tan commented 2 years ago

Related: I've found that using projects causes coverage* params to not be used from the project configurations.

jest.config.js

module.exports = {
  projects: ['<rootDir>/jest-custom-project.config.js'],
};

jest-custom-project.config.js

{
  "collectCoverageFrom": [
    "**/*.{js,jsx}",
    "!**/node_modules/**",
    "!**/vendor/**"
  ],
  ...
}

You need to configure collectCoverageFrom in jest.config.js which is unfortunate since you'd want to keep the coverage configuration tied to the projects being run (i.e. support coverage from projectConfig)

https://github.com/facebook/jest/blob/cdc64c6691f5a8486bbba0f16364a828e6e110a1/packages/jest-config/src/index.ts#L176-L182

github-actions[bot] commented 1 year ago

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.

Yegorich555 commented 1 year ago

Any changes ?

github-actions[bot] commented 11 months ago

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.

Bessonov commented 11 months ago

comment

ernestostifano commented 7 months ago

+1