Tangible Bytes

A Web Developer’s Blog

Jest Coverage in SonarCloud

Setting up Sonarcloud integration with Gitlab was so easy as to be not worth documenting - just setup an account at each, import your projects on Sonarcloud and follow the step by step guide to start analysis.

But getting test coverage reports was harder.

The reports generated by default were very helpful and reassured me that while I am learning a new framework - I am not leaving any horrible security holes.

Sonar was also nagging me to get on top of Unit tests - sometimes you need a prod to do the right thing.

So I wrote some - but they didn’t show up.

Getting them to work took a while as the process doesn’t seem very well documented.

You need to do four things

  1. Format coverage reports so that sonar can parse them
  2. Make your test runs output coverage reports
  3. Tell Sonar where the reports are
  4. Make all this happen in your gitlab pipelines

Step 1 - Sonar compatible coverage reports

Install the jest-sonar-reporter as a dev dependency on your project

The project is archived on github but still seems to be the current tool.

npm i -D jest-sonar-reporter

Step 2 - Output Coverage reports

Run tests with additional parameters to output coverage info in the right format

CI=true npm test -- --coverage --testResultsProcessor=jest-sonar-reporter

Check that you now have a ./coverage directory with human readable html reports in ./coverage/lcov-report/

There should also be coverage/clover.xml and coverage/lcov.info

Step 3 - Configure Sonar to read these files

in sonar-project.properties configure where sources, tests, reports, and coverage are.

sonar.sources=src
sonar.exclusions=src/__tests__/**
sonar.tests=src/__tests__
sonar.testExecutionReportPaths=test-report.xml
sonar.javascript.lcov.reportPaths=coverage/lcov.info

It’s great to run sonar scanner locally at this point to test everything is working - I started off testing it all via gitlab pipelines which is slow and makes a mess of you git history.

Download the scanner

Run with host url and token parameters from your setup (you can read these from gitlab)

SONAR_HOST_URL=https://sonarcloud.io SONAR_TOKEN=your_key sonar-scanner

Hopefully at this point the coverage report will show up in Sonarcloud.

I find the scanner output quite verbose and not all that informative - but it is worth reviewing if something goes wrong - there is some info in there.

Step 4 - Gitlab CI pipeline

You now need to make sure that the sonar scanner running on gitlab has access to coverage data

This is my config to do that - just ensuring test reports are run before the scan.

variables:
  SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
  GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
sonarcloud-check:
  image:
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""]
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script:
    - npm install
    - npm test -- --coverage --testResultsProcessor=jest-sonar-reporter
    - sonar-scanner
  only:
    - merge_requests
    - master
    - develop

And we’re done

Now I just need to write more tests.

Sonar Screenshot

It doesn’t seem like something that should be so hard but it took me a while to figure out - I hope this is helpful to somebody.

If you want to take a look at the project I was working on for this it is all open source so help yourself.

Reports

https://sonarcloud.io/dashboard?id=tangiblebytes_bookingui

Source Code

https://gitlab.com/tangiblebytes/spacebooking/bookingui