I have a Ruby on Rails project that I want to display test coverage in SonarQube. The project is built with Jenkins which sends the results to SonarQube. Unit tests are run with rspec and code coverage is calculated with SimpleCov. SonarQube requires that code coverage report is generated in json format so I used simplecov-json in my rails_helper.rb
:
if Rails.env.development? || Rails.env.test?
require 'simplecov'
require 'simplecov-json'
SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter
SimpleCov.start
end
Code coverage report is generated successfully and saved to coverage
folder like this (from Jenkins console output):
Coverage report generated for RSpec to /my-project/coverage/coverage.json. 2000 / 2000 LOC (100.0%) covered.
I configured my sonar-project.properties
like this (to read the coverage report):
sonar.sources=.
sonar.exclusions=**/*_test.go,**/vendor/**,**/coverage/**
sonar.tests=.
sonar.test.inclusions=**/*_spec.rb
sonar.test.exclusions=**/vendor/**
sonar.ruby.coverage.reportPaths=coverage/coverage.json
sonar.ruby.coverage.framework=RSpec
Jenkins builds the project, runs the tests, generates the coverage report, sends the results to SonarQube. But SonarQube always displays 0% coverage for some reason.
Running sonar-scanner -X
(debug mode) shows this error (Jenkins console log):
15:52:30.458 ERROR: Cannot read coverage report file, expecting standard SimpleCov resultset JSON format: 'coverage/coverage.json'
java.lang.ClassCastException: java.lang.String cannot be cast to org.sonarsource.analyzer.commons.internal.json.simple.JSONObject
at org.sonarsource.ruby.plugin.SimpleCovSensor.mergeFileCoverages(SimpleCovSensor.java:112)
at org.sonarsource.ruby.plugin.SimpleCovSensor.execute(SimpleCovSensor.java:71)
at org.sonar.scanner.sensor.SensorWrapper.analyse(SensorWrapper.java:45)
It looks like SonarQube is having trouble reading the json coverage report - it’s not formatted in the way it expects.
Sonar's SimpleCov support expects the .resultset.json
file, not the output of the JSON formatter. You'll need to point the configuration to the result set instead:
sonar.ruby.coverage.reportPaths=coverage/.resultset.json