Merge Coverage Reports
The following usage scenarios may require merging coverage reports:
- When the code is executed in different environments, like Node.js
server sideand browserclient side(Next.jsfor instance). Each environment may generate its own coverage report. Merging them can give a more comprehensive view of the test coverage. - When the code is subjected to different kinds of testing. For example,
unit testswithJestmight cover certain parts of the code, whileend-to-end testswithPlaywrightmight cover other parts. Merging these different coverage reports can provide a holistic view of what code has been tested. - When tests are run on different machines or containers, each might produce its own coverage report. Merging these can give a complete picture of the test coverage across all machines or shards.
Automatic Merging
- The
MCRwill automatically merge all the added coverage data when executinggenerate(). And it supports adding coverage data asynchronously across processes, see Multiprocessing Support - For
Next.js, it can actually add coverage data including both server side and client side before executinggenerate(), see example nextjs-with-playwright - Using
Codecov, a popular online code coverage service, which supports automatic merging of reports. Please use reportcodecov, it will generate report filecodecov.json. If multiplecodecov.jsonfiles are generated, upload all these files, they will be automatically merged. see Codecov and merging reports
Manual Merging
If the reports cannot be merged automatically, then here is how to manually merge the reports. First, using the raw report to export the original coverage data to the specified directory.
Unit Test Example
For example, we have raw coverage data from unit test, which is output to ./coverage-reports/unit/raw. Unit test examples:
Jest+ jest-monocart-coverageVitest+ vitest-monocart-coverage
js
const coverageOptions = {
name: 'My Unit Test Coverage Report',
outputDir: "./coverage-reports/unit",
reports: [
['raw', {
// relative path will be "./coverage-reports/unit/raw"
// defaults to raw
outputDir: "raw"
}],
['v8'],
['console-details']
]
};E2E Test Example
We also have raw coverage data from e2e test, which is output to ./coverage-reports/e2e/raw. E2E test examples:
Playwright+ monocart-reporter with coverage APIPlaywright+MCR, see playwright-coverage- see more Integration Examples
Merge Script
Then create a script merge-coverage.js to generate a merged report with option inputDir.
js
// merge-coverage.js
const fs = require('fs');
const { CoverageReport } = require('monocart-coverage-reports');
const inputDir = [
'./coverage-reports/unit/raw',
'./coverage-reports/e2e/raw'
];
const coverageOptions = {
name: 'My Merged Coverage Report',
inputDir,
outputDir: './coverage-reports/merged',
// filter for both unit and e2e
entryFilter: {
'**/node_modules/**': false,
'**/*': true
},
sourceFilter: {
'**/node_modules/**': false,
'**/src/**': true
},
sourcePath: (filePath, info) => {
// Unify the file path for the same files
// For example, the file index.js has different paths:
// unit: unit-dist/src/index.js
// e2e: e2e-dist/src/index.js
// return filePath.replace("unit-dist/", "").replace("e2e-dist/", "")
return filePath;
},
reports: [
['v8'],
['console-details']
],
onEnd: () => {
// remove the raw files if it useless
// inputDir.forEach((p) => {
// fs.rmSync(p, {
// recursive: true,
// force: true
// });
// });
}
};
await new CoverageReport(coverageOptions).generate();Running the Merge
Running script node path/to/merge-coverage.js after all the tests are completed. All the command scripts are probably like following:
json
{
"scripts": {
"test:unit": "jest",
"test:e2e": "playwright test",
"merge-coverage": "node path/to/merge-coverage.js",
"test": "npm run test:unit && npm run test:e2e && npm run merge-coverage"
}
}see example: merge-code-coverage