sonarqube gradle plugin excluding jacoco integration tests - gradle

I'm trying to integrate the sonarqube gradle plugin with the jacoco plugin:
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.1'
apply plugin: 'org.sonarqube'
apply plugin: 'jacoco'
My build/jacoco folder contains:
integrationTest.exec
test.exec
However, the sonarqube plugin only recognises the 'test.exec' file:
18:20:45.130 INFO - JaCoCoItSensor: JaCoCo IT report not found: C:\Users\abc3\Downloads\sme-letter\target\jacoco-it.exec
:
18:05:55.609 INFO - Analysing C:\Users\abc3\Downloads\sme-letter\build\jacoco\test.exec
How do I get the sonarqube plugin to recognise 'integrationTest.exec'
Thanks
Mark

I'm not really sure, whether this will work for Gradle plugun, but you may try.
Sonar has a property to specify the name of the integration tests JaCoCo report. This property is called sonar.jacoco.itReportPath (sonar.jacoco.reportPath for unit tests report).
And as far as I know, gradle sonar plugin let you add custom properties to it. So you can change IT report name via properties as follows:
sonarqube {
properties {
property "sonar.jacoco.itReportPath", "build/jacoco/ integrationTest.exec"
}
}

It works for me, but only after merging all jacoco reports into one file AND (important) deleting all other reports
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.junit.reportsPath", "$projectDir/build/test-results"
property 'sonar.jacoco.reportPaths', "${rootProject.buildDir}/jacoco/mergeJacoco.exec"
And you need a merge jacoco task
Task mergeJacoco = tasks.create('mergeJacoco', JacocoMerge, {
doFirst {
delete "$buildDir/jacoco/mergeJacoco.exec"
}
destinationFile(new File(buildDir, 'jacoco/mergeJacoco.exec'))
executionData fileTree('./').include('**/*.exec-partial')
doLast {
delete fileTree('./').include('**/test.exec-partial')
}
})
mergeJacoco.outputs.upToDateWhen { false }
project.tasks["sonarqube"].dependsOn mergeJacoco
mergeJacoco.mustRunAfter ":myProject:test"
And setup jacoco to use those "partial" files
subprojects {
....
jacoco {
destinationFile file("$buildDir/jacoco/test.exec-partial")
append = false
includes = ['com.mypackage.*']
}
}
You'll get unit and IT reports mixed in one, but that's the best I could get

Related

How to integrate jacoco plugin with gradle?

I need to integrate jacoco plugin in to build.gradle or grade.properties file. anyone help me with setting this
Please check documentation of JaCoCo Gradle Plugin - https://docs.gradle.org/current/userguide/jacoco_plugin.html
For example you can add
apply plugin: 'jacoco'
// ...
test {
jacoco {
enabled = true
destinationFile = file("$buildDir/jacoco/jacoco.exec");
}
}
to your build.gradle file.

Report is not getting added as part of build phase

Added JACOCO HTML report in my Gradle build for java project. But Report was not getting added as part of build phase, need to execute gradle task jacocoTestReport to get report.
Pseudo Gradle build file :
apply plugin : 'java'
apply plugin : 'jacoco'
repositories {
jcenter()
maven { maveno repo url }
}
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.enabled true
}
}
dependencies {
}
jacocoTestReport.mustRunAfter test
How to include Jacoco task in build phase of the project? So that no separate task needs to be executed.
The methods mustRunAfter and shouldRunAfter only affect the execution order of tasks that will be executed anyway (e.g. when passed via command line).
To cause a task to be executed when another task is executed, use either dependsOn or finalizedBy.
In your case, you could use finalizedBy on the test task:
test.finalizedBy jacocoTestReport

Feed jacoco coverage report to SonarQube using TeamCity but it shows 0% coverage

I have a gradle project with some codes in src/main/java and some unit tests in src/test/java
Below is snippet from build.gradle
apply plugin: "jacoco"
sourceSets {
main {
java { srcDir 'src/main/java' }
}
}
test {
jacoco {
append = false
destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
classDumpDir = file("$buildDir/jacoco/classpathdumps")
}
}
jacoco {
toolVersion = "0.7.8"
}
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination "${buildDir}/reports/jacoco/jacocoHtml"
}
}
On TeamCity, I have 2 steps, first is Gradle step with command gradle clean jacocoTestReport build and second step is SonarQube runner with the following parameters:
-Dsonar.sources=%system.teamcity.build.checkoutDir%/src
-Dsonar.java.binaries=%system.teamcity.build.checkoutDir%/build/classes
-Dsonar.branch.name=%teamcity.build.branch%
-Dsonar.jacoco.reportPaths=%system.teamcity.build.checkoutDir%/build/jacoco/jacocoTest.exec
However, on SonarQube dashboard, my project still shows to have 0% Coverage. Please advise me if I feed jacoco coverage report correctly to SonarQube (Version 6.7)
If you are using TeamCity JaCoCo integration for Gradle runner the coverage should be automatically. Make sure you've provided "Binaries location:" in the SonarQube Runner. In this case the build log will contain such lines:
# before SonarQube start:
-Dsonar.java.coveragePlugin=jacoco
-Dsonar.jacoco.reportPath=/.../buildAgent/temp/buildTmp/JACOCO8457480821230827929coverage/jacoco.exec
# while SonarQube is executed:
Sensor JaCoCoSensor
Analysing /.../buildAgent/temp/buildTmp/JACOCO8457480821230827929coverage/jacoco.exec
In case you want to use JaCoCo plugin in your Gradle script you should manually set coverage type and data location in the SonarQube Runner step
-Dsonar.java.coveragePlugin=jacoco
-Dsonar.jacoco.reportPaths=%system.teamcity.build.checkoutDir%/build/jacoco/jacocoTest.exec
So try to add "sonar.java.coveragePlugin" property

Generate coverage for other modules

My project structure is as follows: :app, :core. :app is the Android application project, and it depends on :core which has all the business logic.
I have Espresso tests for :app, and I am able to run and get coverage report thanks to all the questions and guides out there. But the coverage is only for code in :app.
How do I get coverage for all projects (:app and :core) resulting from my Espresso instrumentation tests? Is this even possible?
Any help is greatly appreciated.
Even if you did not mention Jacoco in your question, it is listed in the tags, so I assume you want to create coverage reports by using it. The Gradle Jacoco plugin (apply plugin: 'jacoco') allows you to create custom tasks of the type JacocoReport.
Defining such a task, you can specify source and class directories as well as the execution data:
task jacocoTestReport(type: JacocoReport) {
dependsOn // all your test tasks
reports {
xml.enabled = true
html.enabled = true
}
sourceDirectories = // files() or fileTree() to your source files
classDirectories = // files() or fileTree() to your class files
executionData = // files() or fileTree() including all your test results
}
For Espresso tests, the execution data should include all generated .ec files. You could define this task in the Gradle root project and link to both the files and the tasks of your subprojects.
There is an example for a custom Jacoco report task, even if it aims on creating an unified report for multiple test types, it can be transfered for this multi-project problem.
By default the JacocoReport task only reports coverage on sources within the project. You'll need to set the additionalSourceDirs property on the JacocoReport task.
app/build.gradle
apply plugin: 'java'
apply plugin: 'jacoco'
// tell gradle that :core must be evaluated before :app (so the sourceSets are configured)
evaluationDependsOn(':core')
jacocoTestReport {
def coreSourceSet = project(':core').sourceSets.main
additionalSourceDirs.from coreSourceSet.allJava
additionalClassDirs.from coreSourceSet.output
}

Gradle - how to exclude Findbugs on /src/test/java

Is there a way to exclude Findbugs execution on classes under /src/test/java. I tried the following but it doesn't seem to work.
classes = classes.filter {
!it.path.contains("**classes\\test\\org*")
}
Sure. The documentation of the Findbugs extension says:
sourceSets : The source sets to be analyzed as part of the check and build tasks.
And the example just above shows an example doing exactly what you want:
apply plugin: "findbugs"
findbugs {
sourceSets = [sourceSets.main]
}
i.e. only analyze the main sourceSet, and not the test sourceSet.
For Gradle 4.5.1
apply plugin: 'findbugs'
findbugs {
findbugsTest.enabled = false
}
It isn't mentioned anywhere in documentation, at least I, as 1 day gradle user, don't find it, but it works.

Resources