Report is not getting added as part of build phase - gradle

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

Related

PMD/Checkstyle reports during compilation Gradle

I am trying to generate PMD and Checkstyle reports during the compileJava and compileTestJava tasks in my gradle build. By default, the PMD and Checkstyle plugins only report bugs during the check and build phases of my project build. I cannot find the code to generate a report inside a task:
compileJava { // generate.pmd.report // generate.checkstyle.report}
compileTestJava {// generate.pmd.report // generate.checkstyle.report}
For pmd the solution is to use a tasks finalizedBy:
tasks.findByName('compileJava').finalizedBy(tasks.findByName('pmdMain')
tasks.findByName('compileTestJava').finalizedBy(tasks.findByName('pmdTest')
combined with pmd config to enable console output:
pmd {
consoleOutput = true
ignoreFailures = true // controls if the build should fail on detecting issues
}

gradle composite build execute tasks transitively

When executing gradle build in a composite gradle build only compileJava task is executed transitively. Others, like the test task are not.
How can I enforce that my tests are also run on build?
I tried:
build.dependsOn gradle.includedBuilds*.task(':build')
but that did not work.
https://docs.gradle.org/current/userguide/composite_builds.html
here is the gist:
// settings
if (file('../myModule').exists()) {
includeBuild('../myModule')
}
// build1
dependencies {
compile 'mygroup:MyModule:1.0.0'
}

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
}

sonarqube gradle plugin excluding jacoco integration tests

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

Resources