azngunit81
azngunit81

Reputation: 1604

Merge coverage for Sonarqube with istabuljs/nyc

I have a typescript project that goes through a Jenkins pipeline and does all the functional tests in parallel (after building the main container). At the end of the pipeline - we create code coverage check and then ship the result out to sonarqube.

here is my package.json:

"test": "npm run test:unit && npm run test:component && npm run test:functional",
"test:component": "mocha --reporter mocha-sonarqube-reporter --reporter-options output=tests/coverage/component/test-xcomponent.xml --recursive -r ts-node/register tests/component/*.ts",
"test:functional": "mocha --reporter mocha-sonarqube-reporter --reporter-options output=tests/coverage/functional/test-xfunctional.xml --recursive -r ts-node/register tests/functional/*.ts",
"test:unit": "mocha --reporter mocha-sonarqube-reporter --reporter-options output=tests/coverage/unit/test-xunit.xml --recursive -r ts-node/register tests/unit/*.ts",
"test:unit:nosq": "mocha --recursive -r ts-node/register tests/unit/*.ts",
"lint": "tslint -t verbose --project tsconfig.json -c tslint.json",
"cover": "nyc --report-dir tests/coverage/all npm run test",
"cover:unit": "nyc --report-dir tests/coverage/unit npm run test:unit",
"cover:functional": "nyc --report-dir tests/coverage/functional -x 'app/repositories' -x 'app/entities' -x 'app/utils' --no-clean npm run test:functional"

my sonar-project.properties is like the following:

sonar.exclusions=**/node_modules/**,**/*.spec.ts,app/entities/**,dependency-check-report/*,tests/coverage/**/*
sonar.tests=tests
sonar.test.inclusions=tests/**/*
sonar.ts.tslintconfigpath=tslint.json
sonar.typescript.lcov.reportPaths=tests/coverage/all/lcov.info

I have two problems with this setup:

Upvotes: 7

Views: 8966

Answers (1)

zero298
zero298

Reputation: 26920

SonarQube does not require XML files for JavaScript coverage, it requires the report to be in lcov format. Please see SonarQube's documentation: JavaScript Coverage Results Import.

In order to generate this lcov report, you can do the following:

  1. Put all of your JSON coverage data (what the browser/harness writes the __coverage__ global to) in a directory, the default is .nyc_output
  2. Run the command nyc report --reporter=lcov --report-dir=.nyc_coverage
  3. This tells nyc that you want to generate a report using all the files in the directory specified by --report-dir (.nyc_coverage in this case) and that you want the report in the format specified by --reporter (lcov in this case)
  4. nyc will create a folder (.nyc_output by default) and write the lcov file there

If you would like, you can also add extra reporters for sanity. I usually add --reporter=text so that it will print out the coverage as well.

So your final command might be:

nyc report \
  --reporter=lcov \
  --reporter=text \
  --report-dir=.nyc_coverage

The = are optional and the command arguments can precede the sub-command, so you can also run the command that you noted:

nyc --reporter lcov --reporter text --report-dir .nyc_coverage report

Additionally, you tell SonarQube where the report is by specifying it on command line:

sonar-scanner \
  -Dsonar.projectKey=whatever \
  -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info

Or you can set it in the project settings:

Project -> Administration -> JavaScript -> Tests and Coverage -> LCOV Files

Upvotes: 12

Related Questions