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
Find and Remove Files with Space Using Find Command on Linux
Using Output of Awk to Run Command
Who Can Access a File with Octal Permissions "000" on Linux/Unix
Bash: Head & Tail Behavior with Bash Script
Where Does Output of Print in Kernel Go
How to See Contents of Hive Orc Files in Linux
Hadoop: Require Root's Password After Enter "Start-All.Sh"
Postgresql on Elastic Beanstalk (Amazon Linux 2)
What Is Terminal Escape Sequence for Ctrl + Arrow (Left, Right,...) in Term=Linux
Ps: Clean Way to Only Get Parent Processes
How to Send Multicast Packets via a Specfic Interface in Linux
Telnet to Login with Username and Password to Mail Server
How to Change Encoding in Many Files
Passing Associative Array as Argument with Bash
Equivalent Date from Gnu to Solaris