sonarqube+jacoco+junit code coverage showing 0% in sonarqube dashboard - java

I am using sonarqube + jacoco for codecoverage, i have junit test case for my java code in below dir structure.
src/main/java/code/abc.java
src/main/test/code/Testabc.java
I want a code coverage on sonarqube dashboard and i am using gradle for the same.
apply plugin: "java"
apply plugin: "org.sonarqube"
apply plugin: "jacoco"
jacoco {
toolVersion = "0.7.9"
reportsDir = file("${project.buildDir}/jacoco/customJacocoReportDir")
}
sonarqube {
properties {
property "sonar.sources", "."
property "sonar.projectName", "javacode"
property "sonar.projectKey", "javacode"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.java.binaries", "/data/tmp/env/"
property "sonar.jacoco.reportPath", "${project.buildDir}/jacoco/test.exec"
}
}
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7"
}
}
I am running gradle sonarqube
I dont know where i am doing wrong? if any one can help to get the coverage of test case written from java code.

It seems to me, that Jacoco test reports are generated in one directory, but SoanrQube is configured to look into another one. Here is the directory you save reports:
reportsDir = file("${project.buildDir}/jacoco/customJacocoReportDir")
and here is Sonar configuration to look up Jacoco results:
property "sonar.jacoco.reportPath", "${project.buildDir}/jacoco/test.exec"
There is customJacocoReportDir directory missed

Here's the minimal config that is working with
gradle 7.5
sonarqube gradle plugin 3.3
jacoco latest version
Gradle snippet:
apply plugin: "org.sonarqube"
apply plugin: "jacoco"
// jacoco task config not needed since I'm using the defaults (latest version, default dir)
// jacoco {
// toolVersion = "0.7.9"
// reportsDir = file("${project.buildDir}/jacoco/customJacocoReportDir")
// }
sonarqube {
properties {
property "sonar.sources", "."
property "sonar.projectName", "javacode"
property "sonar.projectKey", "javacode"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.java.binaries", "/data/tmp/env/"
// no need to define sonar.jacoco.reportPaths or sonar.coverage.jacoco.xmlReportPaths as sonarqube
// finds the xml report in the default location (build/reports/jacoco/test/jacocoTestReport.xml)
// property "sonar.jacoco.reportPath", "${project.buildDir}/jacoco/test.exec"
}
}
jacocoTestReport {
reports {
xml.enabled true // to be sure xml report is created (sonarqube knows jacoco's default report location)
}
}

Related

Jacoco code coverage for Sonarqube 8 using Gradle

Code Coverage is showing 0% on dashboard
build.gradle file
plugins {
id "org.sonarqube" version "2.8"
id "java"
id "idea"
id "jacoco"
}
jacoco {
toolVersion = "0.8.5"
}
jacocoTestReport {
reports {
html.enabled true
xml.enabled true
xml.destination file("${buildDir}/reports/jacoco.xml")
}
}
plugins.withType(JacocoPlugin) {
tasks["test"].finalizedBy 'jacocoTestReport'
}
sonarqube {
properties {
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.host.url", "http://169.254.1.100:9000"
property "sonar.coverage.jacoco.xmlReportPath", "${buildDir}/reports/jacoco.xml"
}
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
// https://mvnrepository.com/artifact/junit/junit
testCompile 'junit:junit:4.12'
}
check.dependsOn jacocoTestReport
Running this command
./gradlew build jacocoTestReport sonarqube
The JacocoTestReport gets generated with the correct code coverage
Sonarqube gradle task produces this log
> Task :sonarqube
SonarScanner will require Java 11 to run starting in SonarQube 8.x
Property 'sonar.jacoco.reportPath' is no longer supported. Use JaCoCo's xml report and sonar-jacoco plugin.
Property 'sonar.jacoco.reportPaths' is no longer supported. Use JaCoCo's xml report and sonar-jacoco plugin.
Been Googling for half a day, and the only real solutions to this problem is the following:
Property 'sonar.jacoco.reportPath' is deprecated. Please use 'sonar.jacoco.reportPaths' instead
This answer here explains the double output of:
Property 'sonar.jacoco.reportPaths' is no longer supported. Use JaCoCo's xml report and sonar-jacoco plugin.
However this seems to not have been added to the gradle plugin as the plugin being used is 2.8, the lastest as of posting.
Is there something I'm missing?
You have to enable XML report property as true.
xml.enabled true
To expand on qasanov's answer, I had to add this to my build.gradle file in order for JaCoCo to generate the XML report, which was then picked up automatically by SonarQube:
jacocoTestReport {
reports {
xml.required = true
}
}
The issue in your configuration is type of the property name. It is sonar.coverage.jacoco.xmlReportPaths and not sonar.coverage.jacoco.xmlReportPath
I am not using the gradle sonar plugin, but using Jenkin Job's -> Execute SonarQube Scanner configuration.
By default Jacoco generates only html files, for SonarQube we need xmlReportPath.
Below code in gradle will enable the xml reporting and will generate the file with default name as jacocoTestReport.xml
jacocoTestReport {
reports {
xml.enabled true
}
}
This generates the following file in Jenkins workspace at location /ws/build/reports/jacoco/test/jacocoTestReport.xml along with
/ws/build/reports/jacoco/html folder which contains all the html file for the coverage reports. This report can be accessed by accessing index.html file located at /ws/build/reports/jacoco/html/index.xml
And path to the Jacoco xml report file to be provided in the below property
sonar.coverage.jacoco.xmlReportPaths=<rootFolder>/build/reports/jacoco/test/jacocoTestReport.xml
This did work for me.
Before this in SonarQube I was not able to see the Coverage and in other project Coverage was shown as 0.0%.
So, in summary SonarQube is not able to see your JaCoCo report file.

Gradle building Spring Boot library without Main Class

I am trying to build a Spring Boot/Gradle project and create a jar without a main class. My purpose is that this project is a library that will be pulled in by other projects therefore the library project does not require a main class to run. Unfortunately, no matter what kind of gradle config I write I keep getting errors when I try to build install about not having a main class or not being able to find the bootJar task.
Here's what my gradle file looks like:
plugins {
id 'org.springframework.boot' version '2.1.7.RELEASE' apply false
}
apply plugin: 'io.spring.dependency-management'
apply plugin: 'maven'
dependencyManagement {
imports {
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
}
}
repositories {
mavenCentral()
}
jar {
enabled = true
}
bootJar.dependsOn fooTask
But when I run this I get the following error:
Could not get unknown property 'bootJar' for root project
'foo-library' of type org.gradle.api.Project.
What in my configuration needs to change?
Disable bootJar in your build.gradle
bootJar {
enabled = false
}

Analysing a Java Gradle project on SonarQube.com with Travis CI

I have a Java Gradle projet hosted on GitHub and connected to travis CI.
On the root of this project, I have:
.travis.yml
language: java
addons:
sonarqube: true
env:
global:
- secure: <the token generated on sonarqube.com>
script:
gradle check
.sonarsource.properties
wallboard.teamAtSonarSource=support
sonar.host.url=http://sonarqube.com
build.gradle
// Uses DSL plugins resolution introduced in Gradle 2.1
plugins {
id "java"
id "jacoco"
id "org.sonarqube" version "1.2"
}
sonarqube {
properties {
property "sonar.projectName", "Java :: Simple Project :: SonarQube Scanner for Gradle"
property "sonar.projectKey", "org.sonarqube:java-gradle-simple"
property "sonar.jacoco.reportPath", "${project.buildDir}/jacoco/test.exec"
}
}
allprojects {
ext.baseVersion = "0.1"
ext.snapshotVersion = true
group = "org.sonarqube"
version = "$baseVersion" + (snapshotVersion ? "-SNAPSHOT" : "")
}
test {
ignoreFailures = true
}
dependencies {
testCompile 'junit:junit:4.12'
}
repositories {
repositories {
maven {
url "http://repo1.maven.org/maven2/"
}
maven {
url "https://plugins.gradle.org/m2/"
}
}
}
I found this one on SonarSource example repo
The travis CI pass but the sonarqube.com analysis do not run. I am new to Travis, SonarQube and Gradle, so I don't know where exactly I am wrong.
Edit: Here is the Travis logs.
SonarQube analysis is not executed. You have to call it explicitly. Something like:
gradle sonarqube
Please read the documentation for the SonarQube Scanner for Gradle.
First, you should create a token at sonarqube.com. It is under My Account > security.
Then you need to add the token to your sonar properties as
sonar.login=XXX
You may also need to change the url to https.
One thing to note is the token is unsecure. To secure the token follow this guide. You will have to pass the token as a variable to gradle. I believe you can do this with -Psonar.login=$SONAR_TOKEN.

Android - Jacoco code coverage ignores Robolectric tests

Trying to get Code coverage on my Robolectric tests in Android utilising Jacoco but it simply refuses to acknowledge my Robolectric tests when creating the reports.
My jacoco.gradle file is as follows:
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.7.6.201602180812"
}
project.afterEvaluate {
android.applicationVariants.all { variant ->
def name = variant.name
def testTaskName = "test${name.capitalize()}UnitTest"
tasks.create(name: "${testTaskName}Coverage", type: JacocoReport, dependsOn: "$testTaskName") {
group = "Reporting"
description = "Generate Jacoco coverage reports for the ${name.capitalize()} build."
classDirectories = fileTree(
dir: "${project.buildDir}/intermediates/classes/${name}",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/BuildConfig.*',
'**/Manifest*.*']
)
sourceDirectories = files(['src/main/java'].plus(android.sourceSets[name].java.srcDirs))
executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")
reports {
xml.enabled = true
html.enabled = true
}
}
}
}
With this setup I can get Coverage reports but I get 0% coverage despite having Robolectric tests in "src/test/java".
If I add in the following code to that file:
android {
testOptions {
unitTests.all {
jacoco {
includeNoLocationClasses = true
}
}
}
}
I get the following error when Gradle tries to sync:
Error:No such property: includeNoLocationClasses for class:
org.gradle.testing.jacoco.plugins.JacocoTaskExtension_Decorated
I know that I need to have Gradle 2.13 to use this includeNoLocationClasses value so in graddle-wrapper.properties I have the following:
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-2.13-20160228000026+0000-all.zip
I am pretty certain I am running Gradle 2.13 with Android plugin version 1.5
In my apps Gradle file I have the following:
//...
apply from: 'jacoco.gradle'
//..
testOptions {
unitTests.returnDefaultValues = true
}
//...
debug {
testCoverageEnabled true
}
And the command I use to run the coverage is:
./gradlew createDebugCoverageReport
So I am wondering why I get the includeNoLocationClasses error despite using the correct Gradle version? And outside of that maybe I am doing something wrong where Jacoco isn't picking up the Robolectric tests in src/test.java ?
I don't see you build.gradle completely, but to have that flag in you have to:
Use gradle 2.13+
Use jacoco 0.7.6.201602180812
You're sure that you use gradle proper version. So, I think, the issue is only in using wrong jacoco.
Mentioning jacoco {toolVersion = "0.7.6.201602180812"} doesn't influence gradle DSL. You should add newer jacoco plugin:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.jacoco:org.jacoco.core:...'
}
}
And you should apply plugin, which you're already doing:
apply from: 'jacoco'
After such configuraiton you don't need jacoco {toolVersion = "..."} more.
Note: consider to update to newer android gradle plugin, 2.2.x is already stable. jacoco also has newer version already 0.7.7.201606060606
One more note: if you see original issue in Android Studio, check that you use wrapper by default and check that you pointed wrapper to gradle 2.13

How to compile project with Google Checkstyle rules with gradle?

I am trying to use Google checkstyle configuration (https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml) but I am constantly getting an error on gradle check:
Unable to create a Checker: cannot initialize module TreeWalker - Unable to instantiate EmptyCatchBlock
I used Gradle to build the project. Below is my gradle.build.
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'checkstyle'
sourceCompatibility = 1.8
version = '1.0'
checkstyle {
toolVersion = "6.3"
}
task "create-dirs" << {
sourceSets*.java.srcDirs*.each { it.mkdirs() }
sourceSets*.resources.srcDirs*.each { it.mkdirs() }
}
jar {
manifest {
attributes 'Implementation-Title': 'xyz',
'Implementation-Version': 0.01
}
}
repositories {
mavenCentral()
}
dependencies {
compile (
['org.apache.logging.log4j:log4j-api:2.2'],
['org.apache.logging.log4j:log4j-core:2.2']
)
testCompile(
['junit:junit:4.11'],
['org.mockito:mockito-core:1.+']
)
}
test {
systemProperties 'property': 'value'
}
uploadArchives {
repositories {
flatDir {
dirs 'repos'
}
}
}
Also, when I try to add XML config file to Checkstyle plugin in IDEA I get similar error but with a stack trace:
org.infernus.idea.checkstyle.exception.CheckStylePluginException: <html><b>The CheckStyle rules file could not be loaded.</b><br>cannot initialize module TreeWalker - Unable to instantiate EmptyCatchBlock</html>
at org.infernus.idea.checkstyle.checker.CheckerFactory.blacklistAndShowMessage(CheckerFactory.java:234)
at org.infernus.idea.checkstyle.checker.CheckerFactory.createChecker(CheckerFactory.java:188)
at org.infernus.idea.checkstyle.checker.CheckerFactory.getOrCreateCachedChecker(CheckerFactory.java:98)
at org.infernus.idea.checkstyle.checker.CheckerFactory.getChecker(CheckerFactory.java:73)
at org.infernus.idea.checkstyle.checker.CheckerFactory.getChecker(CheckerFactory.java:41)
I cannot figure out what am I doing wrong. Any help would be appreciated.
Gradle version: 2.2
You can add this configuration into your build.gradle file:
configurations {
checkstyleOverride
}
dependencies {
checkstyleOverride('com.puppycrawl.tools:checkstyle:6.11.2')
}
tasks.withType(Checkstyle) {
checkstyleClasspath = project.configurations.checkstyleOverride
}
Enjoy!
The problem lies in the fact that com.puppycrawl.tools.checkstyle.checks.blocks.EmptyCatchBlockCheck was indeed added to checkstyle but for version 6.4-SNAPSHOT. As it can be seen in checkstyle repository (pom.xml history) version 6.4-SNAPSHOT was introduced on the 02.02.2015 and EmptyCatchBlockCheck class was created on 18.02.2015.
Gradle still uses version 6.3 as in the following log extract:
:checkstyleMain
Download https://repo1.maven.org/maven2/com/puppycrawl/tools/checkstyle/6.3/checkstyle-6.3.pom
So there's simply no class You'd like to use.
According to the docs checkstyle classpath can be specified with checkstyleClasspath property - you can try to set it up manually.
I've also prepared a demo with 6.4-SNAPSHOT version, it can be found here. Checkstyle jar was built with mvn clean package with source taken from this repo.
Here is an approach that works with the (currently) latest versions of Gradle & Checkstyle (Gradle 6.1.1 & Checkstyle 8.29):
plugins {
id 'java'
id 'checkstyle'
}
configurations {
checkstyleConfig
}
dependencies {
checkstyleConfig("com.puppycrawl.tools:checkstyle:8.29") { transitive = false }
}
checkstyle {
toolVersion '8.29'
config = resources.text.fromArchiveEntry(configurations.checkstyleConfig, 'google_checks.xml')
}
Note that the Checkstyle dependency excludes transitive dependencies, otherwise the resources.text.fromArchiveEntry will fail since multiple JAR files will be present, and it will be unable to select a single one.

Categories

Resources