Gradle jacoco plugin help


We are trying to implement a test coverage threshold to fail the build if the coverage drops below a certain limit. We are using the jacocoTestCoverageVerification gradle task as listed here:

The build doesn’t seem to fail with this configuration. Do we need the verification task to depend on another task.

Here is the related configuration in our build.gradle file:

I apply the plugin jacoco with my other plugins.

def getProjectList() {
// These projects are considered. Replace with a different list as needed.
subprojects + project

task jacocoMerge(type: JacocoMerge) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = ‘Merge the JaCoCo data files from all subprojects into one’
project.afterEvaluate { // do it at the end of the config phase to be sure all information is present
FileCollection execFiles = project.objects.fileCollection() // an empty FileCollection
getProjectList().each { Project subproject ->
if (subproject.pluginManager.hasPlugin(‘jacoco’)) {
def testTasks = subproject.tasks.withType(Test)
dependsOn(testTasks) // ensure that .exec files are actually present

testTasks.each { Test task ->
// The JacocoTaskExtension is the source of truth for the location of the .exec file.
JacocoTaskExtension extension = task.getExtensions().findByType(JacocoTaskExtension.class)
if (extension != null) {
execFiles.from extension.getDestinationFile()
executionData = execFiles
doFirst {
// .exec files might be missing if a project has no tests. Filter in execution phase.
executionData = executionData.filter { it.canRead() }

def getReportTasks(JacocoReport pRootTask) {
getProjectList().collect {
it.tasks.withType(JacocoReport).findAll { it != pRootTask }

task jacocoRootReport(type: JacocoReport, dependsOn: tasks.jacocoMerge) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = ‘Generates an aggregate report from all subprojects’

logger.lifecycle 'Using aggregated file: ’ + tasks.jacocoMerge.destinationFile
executionData.from tasks.jacocoMerge.destinationFile

project.afterEvaluate {
// The JacocoReport tasks are the source of truth for class files and sources.
def reportTasks = getReportTasks(tasks.jacocoRootReport)
classDirectories.from project.files({
reportTasks.collect {it.classDirectories.files.collect{
fileTree(dir: it, exclude: [
}}.findAll {it != null}
sourceDirectories.from project.files({
reportTasks.collect {it.sourceDirectories}.findAll {it != null}

Here is the task configuration in our gradle file - Note that its a multi module project:

jacocoTestCoverageVerification {
violationRules {
rule {
enabled = true
element = ‘CLASS’
includes = [‘*’]
limit {
counter = ‘LINE’
minimum = 20000000
check.dependsOn jacocoTestCoverageVerification

Please let me know if I can add any other details to this to move further.