I am new to gradle. I am using the below code. But it generates coverage for unit test cases. But it didn't generate for integration test cases. I have my test classes in the package src/test/java.
test {
dependsOn jettyRunWar
ignoreFailures true
finalizedBy jettyStop
}
apply plugin: 'jacoco'
jacocoTestReport {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
additionalSourceDirs = files(sourceSets.main.allJava.srcDirs)
}
Using Gradle 5.4.1 (and now 5.5.1), I was able to get a report after any test task, currently I have both test
and integrationTest
tasks.
EDIT3: Fixed a potential bug when executing only some test tasks
executionData
in doLast
/ doFirst
blocks, it was an error from my part. For more information checks this gradle github ticketdoLast
/ doFirst
block)
executionData { tasks.withType(Test).findAll { it.jacoco.destinationFile.exists() }*.jacoco.destinationFile }
EDIT2: The solution is the same, I just tweaked
jacoco.reportsDir
,tasks.withType(Test)
instead of just [test, integrationTest]
executionData
is done in the doFirst
block instead of doLast
EDIT: After looking at the documentation of JacocoReport
, there's a variant JacocoReport:executionData that take Gradle tasks directly. It works because the JaCoCo plugin adds a JacocoTaskExtension
extension to all tasks of type Test
. Which is then less error prone.
jacocoTestReport {
// The JaCoCo plugin adds a JacocoTaskExtension extension to all tasks of type Test.
// Use task state to include or not task execution data
// https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskState.html
// This declaration will be used as a closure, notice there no wrapping parenthesis
executionData tasks.withType(Test).findAll { it.state.executed }
// If the above instruction really don't work, there maybe some things that intervene in the process, in this case, you may be a bit more lucky with this instruction
// executionData { tasks.withType(Test).findAll { it.jacoco.destinationFile.exists() }*.jacoco.destinationFile }
reports {
xml.enabled true
xml.destination(file("${jacoco.reportsDir}/all-tests/jacocoAllTestReport.xml"))
html.enabled true
html.destination(file("${jacoco.reportsDir}/all-tests/html"))
}
}
And the same trick can be applied to sonarqube
task :
sonarqube {
group = "verification"
properties {
// https://jira.sonarsource.com/browse/MMF-1651
property "sonar.coverage.jacoco.xmlReportPaths", jacocoTestReport.reports.xml.destination
properties["sonar.junit.reportPaths"] += integrationTest.reports.junitXml.destination
properties["sonar.tests"] += sourceSets.integrationTest.allSource.srcDirs
// ... other properties
}
}
Older but very working answer. Also using the knowledge above (that Test
s task are extended by JacocoTaskExtension
) it's possible to replace the manual file
configuration of executionData
by test.jacoco.destinationFile
and integrationTest.jacoco.destinationFile
.
// Without it, the only data is the binary data,
// but I need the XML and HTML report after any test task
tasks.withType(Test) {
finalizedBy jacocoTestReport
}
// Configure the report to look for executionData generated during the test and integrationTest task
jacocoTestReport {
executionData(file("${project.buildDir}/jacoco/test.exec"),
file("${project.buildDir}/jacoco/integrationTest.exec"))
reports {
// for sonarqube
xml.enabled true
xml.destination(file("${project.buildDir}/reports/jacoco/all-tests/jacocoAllTestReport.xml"))
// for devs
html.enabled true
html.destination file("${project.buildDir}/reports/jacoco/all-tests/html")
}
}
sonarqube {
group = "verification"
properties {
// https://jira.sonarsource.com/browse/MMF-1651
property "sonar.coverage.jacoco.xmlReportPaths", ${project.buildDir}/test-results/integrationTest"
properties["sonar.junit.reportPaths"] += "${project.buildDir}/test-results/integrationTest"
properties["sonar.tests"] += sourceSets.integrationTest.allSource.srcDirs
// ... other properties
}
}
project.tasks["sonarqube"].dependsOn "jacocoTestReport"