Sonar - Measure Code Coverage Using Cobertura

SONAR - Measure Code Coverage using Cobertura

You configure the Sonar task to upload unit test and cobertura reports generated by other parts of your build logic.

This is in contrast to Maven which has a standard build life-cycle that Sonar is able to leverage.

Unit test and code coverage

The following logic runs the unit tests with cobertura instrumented classes. An XML coverage report is generated by cobertura at the end:

<target name="instrument-classes" depends="compile-tests">
<taskdef resource="tasks.properties" classpathref="test.path"/>
<cobertura-instrument todir="${instrumented.classes.dir}" datafile="${build.dir}/cobertura.ser">
<fileset dir="${classes.dir}"/>
</cobertura-instrument>
</target>

<target name="junit" depends="instrument-classes">
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<path refid="test.path"/>
<pathelement path="${instrumented.classes.dir}"/>
<pathelement path="${test.classes.dir}"/>
</classpath>

<formatter type="xml"/>

<batchtest fork="yes" todir="${test.reports.dir}">
<fileset dir="${test.src.dir}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
</target>

<target name="test" depends="junit">
<cobertura-report format="xml" datafile="${build.dir}/cobertura.ser" destdir="${cobertura.reports.dir}"/>
</target>

Invoking Sonar

I normally use a very simple Sonar target:

<target name="sonar" depends="test">
<taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml" classpathref="sonar.path"/>

<sonar:sonar key="${sonar.project.key}" version="${sonar.project.version}" xmlns:sonar="antlib:org.sonar.ant"/>
</target>

And use a properties file to control all aspects of Sonar's behaviour:

sonar.project.key=org.demo:demo
sonar.project.version=1.0-SNAPSHOT
sonar.projectName=Demo project

sonar.host.url=http://myserver:9000
sonar.jdbc.url=jdbc:mysql://myserver:3306/sonar?useUnicode=true&characterEncoding=utf8
sonar.jdbc.driverClassName=com.mysql.jdbc.Driver
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar

sonar.sources=${src.dir}
sonar.tests=${test.src.dir}
sonar.binaries=${classes.dir}

sonar.dynamicAnalysis=reuseReports
sonar.surefire.reportsPath=${test.reports.dir}
sonar.java.coveragePlugin=cobertura
sonar.cobertura.reportsPath=${cobertura.reports.dir}/coverage.xml

Demonstrates how Sonar can be configured to pick up the unit test reports created by junit and the code coverage report generated by cobertura.

The build does not have to run on the same server as Sonar. In that case one must provide the remote Sonar URL and JDBC credentials.

Using Cobertura files for code coverage with SonarQube from Azure DevOps Pipelines

Is it possible to use that file to cover my C# project?

I am afraid there is no such out of box property to cover C# project with Cobertura format.

Just as you read, the cobertura is for python and flex. For the C#, we need to use the sonar.cs.dotcover.reportsPaths or sonar.cs.opencover.reportsPaths with the format dotCover or OpenCover.

To resolve this issue, you could try to use a custom powershell script provided by Chameera Dulanga as workaround:

$Env:DOTNET_ROOT= (Get-Command dotnet).Path.Replace('dotnet.exe','sdk\2.1.300')
dotnet tool install dotnet-reportgenerator-globaltool --tool-path . --version 4.0.12
dotnet tool install coverlet.console --tool-path . --version 1.4.1
mkdir .\reports
$testDll = gci -Recurse | ?{ $_.FullName -like ("*bin\{0}\{1}" -f "$(BuildConfiguration)", "$(TestDllFile)") }
$coverlet = "$pwd\coverlet.exe"
& $coverlet $testDll.FullName --target "dotnet" --targetargs ("vstest {0} --logger:trx" -f $testDll.FullName) --format "cobertura"
gci -Recurse |
?{ $_.Name -eq "coverage.cobertura.xml"} |
%{ &"$pwd\reportgenerator.exe" ("-reports:{0}" -f $_.FullName) "-targetdir:reports" "-reportstypes:HTMLInline;HTMLChart" }

You could check his blog Running ASP.NET NUnit Tests in Azure DevOps Build Pipeline and Publishing Results to Sonar Cloud (LINK BROKEN) for some details.

Hope this helps.

Code coverage - Azure Pipelines SonarQube

Update: Apparently, SonarQube does not allow publishing Cobertura results file by default (Or atleast I could not get it to run).

Used a workaround - I had to pass the OpenCover test results file to SonarQube. And for pushing the results onto Azure Devops, I had to use reportgenerator tool to convert the results to Cobertura , before passing them to Azure Devops.

Code Coverage: Cobertura and SonarQube 5.3 Maven Integration

I did not get any answer yet from anyone. But I solved this on my own as described in the

sonar importing cobertura.ser.

The issue is sonar-maven-plugin was expecting coverage.xml file but I was pointing to cobertura.ser.

I changed it to

<sonar.cobertura.reportPath>${project.basedir}/target/site/cobertura/coverage.xml</sonar.cobertura.reportPath>

Secondly, I found one issue with cobertura-maven-plugin (version: 2.7) it is not generating coverage.xml file even though in report format I have specified xml. This issues is already pointed in the below stackoverflow link

Maven Cobertura plugin not generating coverage.xml

<plugin>
<!-- use mvn cobertura:cobertura to generate cobertura reports -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
<configuration>
<formats>
<format>xml</format>
</formats>
</plugin>

I have to pass -Dcobertura.report.format=xml this property to generate the coverage.xml

The final plugin configuration looks like this

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
<configuration>
<instrumentation>
<include>
<include>**/*.class</include>
</includes>
</instrumentation>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<id>clean</id>
<phase>pre-site</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
<execution>
<id>instrument</id>
<phase>site</phase>
<goals>
<goal>instrument</goal>
<goal>cobertura</goal>
</goals>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</execution>
</executions>
</plugin>


<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.0.2</version>
</plugin>

</plugins>
</build>

<reporting>
<plugins>
<plugin>

<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
<configuration>
<formats>
<format>xml</format>
</formats>
</configuration>
</plugin>
</plugins>
</reporting>

And I am using the below command to execute the code coverage and publishing to SonarQube

clean install cobertura:cobertura sonar:sonar -Dcobertura.report.format=xml

Sonar Component view and cobertura code coverage report view differ

You don't see all the classes on the code coverage drilldown page because classes which have 100% code coverage are hidden (as there's nothing to do about them). On the other side, the component page shows all the components, whatever their measures on specific metrics are.

This is a general behaviour in Sonar. You can find all the classes though the components page, because this service is made to navigate through your code. But in the drilldown pages (measures or violations based), you will only see classes which have "issues" because this service is made to hunt quality flaws.

  • in violation drilldown, you won't see classes which don't have any violation

  • in measure drilldown, you won't see classes which have the "best value" for the selected metric (=> 100% for code coverage for instance)

SonarQube not picking up Cobertura code coverage

Ok the solution was quite obvious. SonarCube 4.1.1 does not come with Cobertura preinstalled, so I installed it and now it works :) Maybe it was preinstalled in 3.2 version, I can't remember.



Related Topics



Leave a reply



Submit