# Gradle jacoco plugin help

**URL:** <https://discuss.gradle.org/t/gradle-jacoco-plugin-help/37618>\
**Category:** Help/Discuss\
**Created:** [September 17, 2020, 12:48am UTC](https://discuss.gradle.org/t/gradle-jacoco-plugin-help/37618 "2020-09-17T00:48:09Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![brahmakss712](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@brahmakss712](https://discuss.gradle.org/u/brahmakss712)\
**Post date:** [September 17, 2020, 12:48am UTC](https://discuss.gradle.org/t/gradle-jacoco-plugin-help/37618/1 "2020-09-17T00:48:09Z")

</div>

Hi,

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: [https://docs.gradle.org/current/dsl/org.gradle.testing.jacoco.tasks.JacocoCoverageVerification.html](https://docs.gradle.org/current/dsl/org.gradle.testing.jacoco.tasks.JacocoCoverageVerification.html)

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 }  
}.flatten()  
}

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: [  
‘ **/domain/** ’  
])  
}}.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 = [‘org.xyz.\*’]  
limit {  
counter = ‘LINE’  
value = ‘COVEREDCOUNT’  
minimum = 20000000  
}  
}  
}  
}  
check.dependsOn jacocoTestCoverageVerification

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

Thanks!
