Setup Code Coverage for Monorepo - SonarQube
Vikas Yadav
Posted on April 23, 2024
In a Monorepo setup, generating a coverage report for each library or app separately is common.
However, tools like the Sonar scanner may encounter difficulties in combining these reports into a single comprehensive one.
This issue arises when running tests with tools like nx affected, where only affected projects generate coverage reports, leaving unaffected projects out.
Consequently, SonarQube may raise quality gate errors due to missing coverage data.
Propose Solution Implemented
To resolve this problem, a custom script can be added to merge coverage reports into one file.
Below is a simple JavaScript function named coveragemerger.js
for this purpose:
const glob = require('glob');
const fs = require('fs').promises;
const path = require('path');
const util = require('util');
const REPORTS_DIR_NAME = 'coverage';
const GREEN = '\x1b[32m%s\x1b[0m';
const BLUE = '\x1b[34m%s\x1b[0m';
const REPORTS_DIR_PATH = path.resolve(process.cwd(), REPORTS_DIR_NAME);
const globPromise = util.promisify(glob);
/**
* Fetches all lcov.info files from coverage directories, excluding node_modules.
* @returns {Promise<string[]>} A promise that resolves with an array of file paths.
*/
const getLcovFiles = function () {
return globPromise(`**/coverage/lcov.info`, { ignore: '**/node_modules/**' });
};
/**
* Creates a temp directory for all the reports.
* @returns {Promise<void>} A promise that resolves when the directory has been created.
*/
async function createTempDir() {
console.log(BLUE, `Creating a temp ${REPORTS_DIR_NAME} directory...`);
try {
await fs.mkdir(REPORTS_DIR_PATH, { recursive: true });
console.log(GREEN, 'Done!');
} catch (err) {
console.error('Error creating directory:', err);
}
}
(async function () {
try {
// Fetch all lcov.info files
const files = await getLcovFiles();
console.log("files are", files);
// Create temp directory
await createTempDir();
// Read all files and join their contents
const mergedReport = await Promise.all(files.map(file => fs.readFile(file, 'utf-8'))).then(contents => contents.join(''));
console.log(BLUE, `Copying the coverage report...`);
// Write the merged report to a new lcov.info file
await fs.writeFile(path.resolve(REPORTS_DIR_PATH, `lcov.info`), mergedReport);
console.log('Code coverage has been saved!');
} catch (err) {
console.error('Error:', err);
}
})();
Azure Pipeline Integration
To integrate this into your pipeline, add the following command to your Azure Pipeline file:
- script: |
node coverageMerger.js
displayName: 'Merge Coverage Reports'
SonarQube Analysis Report
Reference:
use this site to check coverage from LCOV https://lcov-viewer.netlify.app/
Posted on April 23, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.