{"id":2964,"date":"2023-10-24T16:28:05","date_gmt":"2023-10-24T14:28:05","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=2964"},"modified":"2023-10-24T22:28:56","modified_gmt":"2023-10-24T20:28:56","slug":"angular-code-coverage-with-sonarqube","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2023\/10\/24\/angular-code-coverage-with-sonarqube\/","title":{"rendered":"How to integrate angular code coverage with Sonarqube"},"content":{"rendered":"\n<p>The Angular CLI can run unit tests and create code coverage reports. Code coverage reports show us any parts of our code base that might not be properly tested by our unit tests.<\/p>\n\n\n\n<p>To generate a coverage report, let&#8217;s run the following command in the root of our project:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ng test --no-watch --code-coverage<\/code><\/pre>\n\n\n\n<p>When the tests are complete, the command creates a new&nbsp;<code><strong><em>\/coverage<\/em><\/strong><\/code>&nbsp;directory in the project.  Let us open the&nbsp;<code>index.html<\/code>&nbsp;file (inside the new directory) to see a report with our source code and code coverage values.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-3.png\" alt=\"\" class=\"wp-image-2973\" width=\"537\" height=\"264\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-3.png 734w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-3-300x148.png 300w\" sizes=\"(max-width: 537px) 100vw, 537px\" \/><\/figure><\/div>\n\n\n\n<p>If we want to create code-coverage reports every time we test, let&#8217;s set the following option in the Angular CLI configuration file,&nbsp;<code>angular.json<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"test\": {\n  \"options\": {\n    \"codeCoverage\": true\n  }\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h4>Code coverage enforcement<\/h4>\n\n\n\n<p>The code coverage percentages let us estimate how much of our code is tested. If in a team, we decides (in ourselves) on a set minimum amount to be unit tested, we can enforce this minimum with the Angular CLI.<\/p>\n\n\n\n<p>For example, suppose we want the code base to have a minimum of 80% code coverage. To enable this, let&#8217;s open the&nbsp;<a href=\"https:\/\/karma-runner.github.io\/\">Karma<\/a>&nbsp;test platform configuration file,&nbsp;<code>karma.conf.js<\/code>, and add the&nbsp;<code>check<\/code>&nbsp;property in the&nbsp;<code>coverageReporter:<\/code>&nbsp;key.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>coverageReporter: {\n  dir: require('path').join(__dirname, '.\/coverage\/&lt;project-name&gt;'),\n  subdir: '.',\n  reporters: &#91;\n    { type: 'html' },\n    { type: 'text-summary' }\n  ],\n  check: {\n    global: {\n      statements: 80,\n      branches: 80,\n      functions: 80,\n      lines: 80\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p><em>The\u00a0<code>check<\/code>\u00a0property causes the tool to enforce a minimum of 80% code coverage when the unit tests are run in the project.<\/em> If the thresholds are not met, karma will return failure.<\/p>\n\n\n\n<p><strong>PS:<\/strong> Read more on coverage configuration options in the\u00a0<a href=\"https:\/\/github.com\/karma-runner\/karma-coverage\/blob\/master\/docs\/configuration.md\">karma coverage documentation<\/a>.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Step 2: Add SonarQube plugin to Karma.Conf<\/h4>\n\n\n\n<p>SonarQube will use the&nbsp;<code>lcov.info<\/code>&nbsp;file to get information about the typescript\/javascript code quality. However, to map a TS\/JS file with its Unit-Test file (Spec file) and make it understand coverage details, you need to use SonarQube plugin with Karma.<\/p>\n\n\n\n<p><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>Let&#8217;s install the plugin <\/strong><\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install -D karma-sonarqube-reporter<\/code><\/pre>\n\n\n\n<p><strong><span class=\"has-inline-color has-vivid-cyan-blue-color\"> Head over to karma.conf.js and make the following changes:<\/span><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/importing the modules\nrequire('karma-sonarqube-reporter')<\/code><\/pre>\n\n\n\n<p><strong><span class=\"has-inline-color has-vivid-cyan-blue-color\">Add sonarqube to the array of reporters:<\/span><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>reporters:&#91;\u2018progress\u2019, \u2018kjhtml\u2019, \u2018sonarqube\u2019]<\/code><\/pre>\n\n\n\n<p><strong><span class=\"has-inline-color has-vivid-cyan-blue-color\">Configure Sonarqube in Karma.conf like this:<\/span><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sonarqubeReporter: {\n      basePath: 'src\/app', \/\/ test files folder\n      filePattern: '**\/*spec.ts', \/\/ test files glob pattern\n      encoding: 'utf-8', \/\/ test files encoding\n      outputFolder: 'reports', \/\/ report destination\n      legacyMode: false, \/\/ report for Sonarqube &lt; 6.2 (disabled)\n      reportName: function (metadata) {\n        \/\/ report name callback, but accepts also a\n        \/\/ string (file name) to generate a single file\n        \/**\n         * Report metadata array:\n         * - metadata&#91;0] = browser name\n         * - metadata&#91;1] = browser version\n         * - metadata&#91;2] = plataform name\n         * - metadata&#91;3] = plataform version\n         *\/\n        return 'sonarqube_report.xml';\n      },\n    },<\/code><\/pre>\n\n\n\n<p><em>If we run&nbsp;<strong><code>ng test --code-coverage --watch=false<\/code>&nbsp;<\/strong>now, there is a folder&nbsp;<code>reports\/<\/code>&nbsp;generated at the project root with&nbsp;<code>sonarqube_report.xml<\/code>&nbsp;file inside the folder.<\/em><\/p>\n\n\n\n<p>Example of tree achitectur: <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-4.png\" alt=\"\" class=\"wp-image-2974\" width=\"657\" height=\"785\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-4.png 657w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-4-251x300.png 251w\" sizes=\"(max-width: 657px) 100vw, 657px\" \/><\/figure><\/div>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Install \u201csonar-scanner\u201d<\/h4>\n\n\n\n<p>Now the time is to configuring the Sonar with Angular application and to do this we need&nbsp;<strong><em>sonar-scanner<\/em><\/strong>&nbsp;node package in the Angular application.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install -D sonarqube-scanner<\/code><\/pre>\n\n\n\n<p>The NPM package also has very good docs (<a rel=\"noreferrer noopener\" href=\"https:\/\/www.npmjs.com\/package\/sonarqube-scanner\" target=\"_blank\">https:\/\/www.npmjs.com\/package\/sonarqube-scanner<\/a>). we can refer to it for further\/more details.<\/p>\n\n\n\n<h4>Create a sonar-project.properties file in our project root<\/h4>\n\n\n\n<p>let&#8217;s Create a file called&nbsp;<strong><em>sonar-project.properties<\/em><\/strong>&nbsp;in our Angular root directory and add below attributes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sonar.host.url=SONAR-QUBE-URL\nsonar.projectKey=Project_Key # Must be unique (Primary key)\nsonar.projectName=PROJECT_NAME # name that will be displayed on the dashboard\nsonar.projectVersion=1.0\nsonar.sourceEncoding=UTF-8\nsonar.sources=src\nsonar.exclusions=**\/node_modules\/**\nsonar.tests=src # Where to pickup test files from\nsonar.test.inclusions=**\/*.spec.ts # only collect these for test-coverage\nsonar.javascript.lcov.reportPaths=src\/coverage\/PROJECT_NAME\/lcov.info\nsonar.testExecutionReportPaths=reports\/sonarqube_report.xml<\/code><\/pre>\n\n\n\n<p>Additionally, we can add the&nbsp;<code>sonar.login<\/code>&nbsp;and&nbsp;<code>sonar.password<\/code>&nbsp;if we have password-protected our SonarQube instance (Only when running locally!).<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-red-color\">Integrate Karma code coverage with Sonarqube<\/span>&nbsp;<\/h4>\n\n\n\n<p>We have both Karma code coverage and Sonar server ready.<\/p>\n\n\n\n<p>Now, let us integrate both using sonar-scanner.<\/p>\n\n\n\n<p>First, add a script called&nbsp;<strong><em>sonar&nbsp;<\/em><\/strong>to your package.json,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"scripts\": {\n    \"sonar\": \"sonar-scanner\"\n}<\/code><\/pre>\n\n\n\n<p>Finally, let&#8217;s run the below command to integrate the Karma coverage with the Sonar server,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm run sonar<\/code><\/pre>\n\n\n\n<p>And we will see the result directly on the Sonar server by navigating to&nbsp;the <strong>corresponding url <\/strong>(setted previously to the  sonar-project.properties file)<\/p>\n\n\n\n<p>example: <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"855\" height=\"315\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-5.png\" alt=\"\" class=\"wp-image-2975\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-5.png 855w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-5-300x111.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2023\/10\/image-5-768x283.png 768w\" sizes=\"(max-width: 855px) 100vw, 855px\" \/><\/figure><\/div>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Update our .gitignore file<\/h4>\n\n\n\n<p>Consider adding these items to our .gitignore file as they should not be tracked in version control.<\/p>\n\n\n\n<p>PS: in our demo, the generated folder name is &#8220;<strong><em>reports<\/em><\/strong>&#8221; . so let us add it in the .gitignore file. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.scannerwork\/*\nreports\/*  <\/code><\/pre>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Conclusion<\/h4>\n\n\n\n<p id=\"6c13\">To integrate karma test coverage with Sonarqube reporter , we have four important steps such as,<\/p>\n\n\n\n<ol><li>Installing the Sonarqube.<\/li><li>Configuring the Sonar with Angular using sonar-project.properties and installing the sonar-scanner package.<\/li><li>Getting the Karma code coverage.<\/li><li>Integrating the Karma code coverage with Sonarqube.<\/li><\/ol>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Angular CLI can run unit tests and create code coverage reports. Code coverage reports show us any parts of our code base that might not be properly tested by our unit tests. To generate a coverage report, let&#8217;s run the following command in the root of our project: When the tests are complete, the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2976,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[37],"tags":[751,748,597,750,749,747,598],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/2964"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=2964"}],"version-history":[{"count":6,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/2964\/revisions"}],"predecessor-version":[{"id":2981,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/2964\/revisions\/2981"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/2976"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=2964"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=2964"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=2964"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}