Issue
Java 8 and Gradle 4.6 here. I'm trying to configure my Gradle build to use the Jacoco Plugin but am having some difficulty. I've already got it working with Checkstyle and Findbugs, such that running ./gradlew clean build
invokes the Checkstyle and Findbugs tasks because they're dependencies of the check
task.
I'm now trying to get Jacoco working such that:
- It excludes my
com.me.myapp.domain.model
package and all of its contents; and - It fails my build if code coverage on the non-excluded classes falls below 70%; and
- Pass or fail, I want an HTML version of the Jacoco report generated under the
build/
directory; and - Ideally I could just use the same Gradle command invocation of
./gradlew clean build
to get Jacoco working like this
My best attempt thus far:
plugins {
id 'java-library'
id 'checkstyle'
id 'findbugs'
id 'jacoco'
}
dependencies {
compile(
'org.hibernate:hibernate-core:5.0.12.Final'
,'com.fasterxml.jackson.core:jackson-core:2.8.10'
,'com.fasterxml.jackson.core:jackson-databind:2.8.10'
,'com.fasterxml.jackson.core:jackson-annotations:2.8.0'
)
testCompile(
'junit:junit:4.12'
)
}
repositories {
jcenter()
mavenCentral()
}
checkstyle {
config = rootProject.resources.text.fromFile('buildConfig/checkstyle/checkstyle.xml')
toolVersion = '8.11'
}
tasks.withType(FindBugs) {
reports {
xml.enabled false
html.enabled true
}
}
findbugs {
excludeFilter = file('buildConfig/findbugs/findbugs-exclude.xml')
}
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.enabled true
}
afterEvaluate {
classDirectories = files(classDirectories.files.collect {
fileTree(dir: it,
exclude: [
'com/me/myapp/domain/model/**'
]
)
})
}
}
jacocoTestCoverageVerification {
violationRules {
rule {
limit {
minimum = 0.7
}
failOnViolation true
}
}
}
jacoco {
toolVersion = "0.8.1"
}
// to run coverage verification during the build (and fail when appropriate)
check.dependsOn jacocoTestCoverageVerification
When I run ./gradlew clean build
with the following build.gradle
above (^^^) Jacoco does fail the build if my coverage is less than 70%. However it does not generate any HTML report for me, which is not helpful at all in terms of fixing it.
Any ideas?
Solution
Please note, that the Gradle Jacoco plugin does provide two totally unrelated functionalities:
- It can generate coverage reports (task type
JacocoReport
) - It can enforce code metrics, e.g. by letting the build fail (task type
JacocoCoverageVerification
)
If the plugin is applied together with the Java Plugin, a task of each of the mentioned types is created, namely jacocoTestReport
and jacocoTestCoverageVerification
. As you can see by the name both of them are associated with the test
task.
However, none of those tasks is automatically included into the regular Gradle build
lifecycle. The reason for not including the report task is simply because it's not necessary for actually building the actual software. For the same reason, the javadoc
task is not included in the build
lifecycle (it might be when creating a javadoc jar). The reason for not including the verification task is trickier, but let's simply quote the docs:
The
JacocoCoverageVerification
task is not a task dependency of thecheck
task provided by the Java plugin. There is a good reason for it. The task is currently not incremental as it doesn't declare any outputs. Any violation of the declared rules would automatically result in a failed build when executing the check task. This behavior might not be desirable for all users. Future versions of Gradle might change the behavior.
You already solved this problem by adding check.dependsOn jacocoTestCoverageVerification
to your build file. This way, the code coverage will be checked with each build (and fail if not sufficient). Now you want to generate the report in all builds, even if it fails due to unsufficient code coverage. You need to ensure that the report is generated before the build might fail. You could use:
jacocoTestCoverageVerification.dependsOn jacocoTestReport
Answered By - Lukas Körfer
Answer Checked By - Marie Seifert (JavaFixing Admin)