Reputation: 1973
Let's say I have these coverage reports:
now I would like to combine these reports and generate a html report.
I'm using this istanbul-combine to do this kind of work. But it seems as if it couldn't find all these coverage json files and I wonder as why is that.
istanbul-combine -d coverage/reports -r lcov -r html /coverage/libs/test/**/coverage-final.json
At the end of the report generation process, it provides me an empty html report.
Upvotes: 3
Views: 5735
Reputation: 79
I encountered this type of issue when combining multiple package coverage results in a monorepo. I used @skyboyer and @Alexus answer which worked really well and was nice and clean but the dependabot on GitHub came up with an indirect security vulnerability resulting from istanbul use. Using istanbuljs's nyc replacement for the istanbul CLI I implemented the same functionality. Unfortunately, it's not nearly as clean but here it is...
I had to rename all of the coverage-final.json files to something unique. Noting my output directory is coverage and the reporter used was json…
lerna exec -- 'export WORKING_DIR=$(basename $LERNA_PACKAGE_NAME) && cp ./<output dir>/coverage-final.json ./<output dir>/coverage-final-$(echo $WORKING_DIR).json'
After which I needed to place all of those files into a centralized directory…
mkdir -p ./coverage && lerna exec -- 'export WORKING_DIR=$(basename $LERNA_PACKAGE_NAME) && cp ./<output dir>/coverage-final-$(echo $WORKING_DIR).json ../../coverage/coverage-final-$(echo $WORKING_DIR).json'
This copied the package contents into a root-level directory named coverage. Moving forward, I needed to merge all of the copied results into one json file. For the output directory I used the same coverage directory at the root level…
nyc merge ./coverage ./coverage/coverage-final.json
And, finally, I needed to transform the result to lcov for input into coveralls (my use-case);
nyc report --reporter=lcov --temp-dir=coverage
Hope that helps! :-) Repository containing implementation
Upvotes: 1
Reputation: 1587
istanbul-combine will be deprecated in favor of istanbul report. I did a migration lately.
This was the old configuration that I was using with istanbul-combine
:
istanbul-combine -d coverage -p none -r lcov -r cobertura coverage/hierarchical-grid/coverage-final.json coverage/tree-grid/coverage-final.json coverage/non-grid/coverage-final.json coverage/grid/coverage-final.json
Changed to:
istanbul report --dir coverage --include coverage/**/coverage-final.json lcov
Upvotes: 5
Reputation: 1973
So I have found a different way to solve this problem. I wrote a small script, which does the following.
mergeCoverage.js
const fs = require( 'fs-extra');
const glob = require('glob');
const { createReporter } = require('istanbul-api');
const istanbulCoverage = require('istanbul-lib-coverage');
const reporter = createReporter();
/* [ Configuration ] */
const rootDir = './coverage/libs';
const reportOut = './coverage/report';
const normalizeJestCoverage = ( obj ) => {
const result = { ...obj };
Object
.entries( result )
.filter( ([k, v] ) => v.data )
.forEach( ([k, v] ) => {
result[k] = v.data;
});
return result;
};
const mergeAllReports = ( coverageMap, reports ) => {
if ( Array.isArray( reports ) === false ) {
return;
}
reports.forEach( reportFile => {
const coverageReport = fs.readJSONSync( reportFile );
coverageMap.merge( normalizeJestCoverage( coverageReport ) );
})
};
const findAllCoverageReports = ( path, callback ) => {
glob( path, {}, ( err, reports )=>{
callback( reports, err );
});
};
const generateReport = ( coverageMap, types ) => {
reporter.dir = reportOut;
reporter.addAll(types || ['html', 'text'] );
reporter.write( coverageMap );
};
async function main () {
const coverageMap = istanbulCoverage.createCoverageMap( {} );
findAllCoverageReports( rootDir + '/**/coverage-final.json', ( reports, err ) => {
if ( Array.isArray( reports ) ) {
mergeAllReports( coverageMap, reports );
generateReport( coverageMap, [ 'text' ] )
}
});
}
main().catch(err => {
console.error(err);
process.exit(1);
});
Upvotes: 3