Combine (merge) multiple karma coverage files

Richard Sloggett
2 min readDec 1, 2020

Karma does a great job of producing coverage reports but on larger projects you may want to consolidate the coverage reports generated by multiple test runs, or runs performed in different environments.

This post demonstrates how to combine (merge) multiple Karma coverage files using a short script you can include in your node project or leverage anywhere else you can execute some javascript.

Coverage file format

The script merges 2 or more coverage files in istanbul json format. If you are using karma-coverage, set coverageReporter.type to “json” in your karma.conf. See karma-coverage/configuration.md at master · karma-runner/karma-coverage (github.com) for detailed karma-coverage configuration details.

If you are using some other coverage tool, so long as it is able to generate coverage files named “coverage-final.json” in istanbul json format you should be good to go.

Dependencies

The script uses some npm libraries, so run the npm command below in your project to install them.

npm i glob istanbul-lib-coverage istanbul-lib-report istanbul-reports --save-dev

Now, the code

Create a new merge-coverage.js file and paste in the code below. With the dependencies above installed and 2 or more coverage-final.json files in any sub-directories named like “coverage-*” running it from a command line or package.json script with “node merge-coverage.js” will generate a merged coverage report in a “coverage-merged” sub-directory.

const fs = require("fs");
const glob = require("glob");
const istanbulCoverage = require("istanbul-lib-coverage");
const istanbulReport = require("istanbul-lib-report");
const istanbulReportGenerator = require("istanbul-reports");
// Helper to load a json blob from a .json file
const getJson = (fileName) => {
const data = fs.readFileSync(fileName);
return JSON.parse(data);
};
// Find any files named "coverage-final.json" (excluding any existing merged one)
let jsonFiles = glob.sync("./coverage-*/**/coverage-final.json")
.filter(possibleFile => possibleFile.indexOf("-merged") === -1);
jsonFiles.forEach(file => console.log(`merging: ${file}`));// Load the json blobs from the discovered .json files
var jsonBlobs = jsonFiles
.map(file => getJson(file));
// Create an empty map and merge in all the loaded maps
let mergedMap = istanbulCoverage.createCoverageMap();
jsonBlobs.forEach(jsonBlob => {
mergedMap.merge(istanbulCoverage.createCoverageMap(jsonBlob));
});
// Create an empty coverage summary and merge in a file coverage
// summary for each of files in the merged map
const mergedSummary = istanbulCoverage.createCoverageSummary();
mergedMap.files().forEach((file) => {
const coverageFile = mergedMap.fileCoverageFor(file);
const coverageSummary = coverageFile.toSummary();
mergedSummary.merge(coverageSummary);
});
// Generate the report
const reportGenerationContext = istanbulReport.createContext({
dir: "./coverage-merged",
defaultSummarizer: "nested",
coverageMap: mergedMap
});
const report = istanbulReportGenerator.create("html-spa");
// call execute to synchronously create and write the report to disk
report.execute(reportGenerationContext);
console.log("Merged coverage generated in ./coverage-merged");

Istanbul reports supports a bunch of different output formats which you can find listed here: istanbuljs/packages/istanbul-reports/lib at master · istanbuljs/istanbuljs (github.com)

“html-spa” is a single page application and “html” is a simpler format with multiple pages. The other formats might be useful to you if you are wanting to feed the merged coverage data into another tool for reporting.

--

--