jest coverageDirectory configuration for project inside monorepo

7.6k views Asked by At

I have a typescript monorepo with jest. Their jest.config.js is

module.exports = {
  clearMocks: true,
  projects: ['<rootDir>/packages/**/jest.config.js'],
  collectCoverage: true,
  coverageReporters: [
    "text-summary",
    "lcov",
  ],
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['*.spec.ts', '*.spec.tsx']
}

At the server package I create the jest.config.js with

const { name } = require('./package.json');

module.exports = {
  displayName: name,
  name,
  'transform': {
    '^.+\\.ts$': 'ts-jest'
  },
  collectCoverageFrom: [
    '<rootDir>/src/**/*.ts'
  ],
  coverageDirectory: '<rootDir>/packages/server/src/tests/coverage',
}

But when I run jest it creates the coverage directory at the root of my monorepo.

I just try to use coverageDirectory: '<rootDir>/src/tests/coverage',, coverageDirectory: 'src/tests/coverage', and coverageDirectory: [__dirname, 'src', 'tests', 'coverage'].join('/'), without success.

The only way I could change the path of coverage directory was to specify it at the jest.config.js of the monorepo, but with this I am unable to specify a coverage directory to each project.

Somebody knows how can I specify a different coverage directory for each project at a monorepo?

2

There are 2 answers

2
robdonn On BEST ANSWER

You can only specify a different coverage directory for each project if you are running jest for each product individually. If you are using a global config (the jest.config.js at the root of your monorepo) then the same coverage settings are applied across them all, including the coverage output directory.

0
Mark On

I did some experimentation with [email protected] and I experienced the same as you: only the global jest.config.js's coverageDirectory is taken into account. Overriding it in project configs made no difference, regardless of what I did with the global config.

I couldn't find a way to make this work while running test projects one at a time. One project would overwrite the other. I'm not sure how we're intended to use this feature, but what worked for me was using environment variables to override the global coverageDirectory path on a per-command basis.

In package.json:

"test:all": "jest",
"test:package-a": "COVERAGE_DIR=coverage/package-a jest --selectProjects PackageA",
"test:package-b": "COVERAGE_DIR=coverage/package-b jest --selectProjects PackageB",

In jest.config.js:

const coverageDir = process.env.COVERAGE_DIR || 'coverage/unified';

module.exports = {
  coverageDirectory: `<rootDir>${coverageDir}`,
}

With this, you can run either of those three scripts and it will populate coverage directories where you want them. I included test:all just for completeness. It feels like an antipattern, but this was the only way I found to run projects one at a time and have the results go to different directories.