32

How can I set the minimum code coverage in Jacoco Gradle?

I want the build to fail if it is not met.

Simulant
  • 19,190
  • 8
  • 63
  • 98
richersoon
  • 4,682
  • 13
  • 44
  • 74

5 Answers5

51

The feature is now available. You simply need to apply the Gradle JaCoCo plugin and define coverage verification like this:

apply plugin: 'jacoco'

jacocoTestCoverageVerification {
    violationRules {
        rule {
            limit {
                minimum = 0.7
            }
        }
    }
}

// to run coverage verification during the build (and fail when appropriate)
check.dependsOn jacocoTestCoverageVerification

The last line is very important as your build would otherwise not fail unless you explicitly run the jacocoTestCoverageVerification task.

More information on the kind of checks you may add is in the documentation of the plugin.

Joffrey
  • 32,348
  • 6
  • 68
  • 100
6

In an Android application this configuration works:

project: build.gradle

buildscript {
    repositories {
        google()
        jcenter()
        maven { url 'https://plugins.gradle.org/m2/' }
    }
    dependencies {
        classpath "com.android.tools.build:gradle:3.1.4"
        classpath "org.jacoco:org.jacoco.core:0.8.2"
    }
}

app: build.gradle

ext.jacoco_version = '0.8.2'
def configDir = "${project.rootDir}/config"
def reportDir = "${project.buildDir}/reports"
def mainSrc = "$project.projectDir/src/main/java"
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
def debugTree = fileTree(dir: "$project.buildDir/intermediates/classes/debug", excludes: fileFilter)
//Jacoco jacocoTestReport
apply plugin: 'jacoco'
jacoco.toolVersion = jacoco_version
task jacocoTestReport(type: JacocoReport, dependsOn: 'testDebugUnitTest') {
    reports {
        xml.enabled = false
        html.enabled = true
    }
    sourceDirectories = files([mainSrc])
    classDirectories = files([debugTree])
    executionData = fileTree(dir: project.buildDir, includes: [
            'jacoco/testDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec'
    ])
}
task jacocoTestCoverageVerification(type: JacocoCoverageVerification, dependsOn: 'jacocoTestReport') {
    sourceDirectories = files([mainSrc])
    classDirectories = files([debugTree])
    executionData = files("${buildDir}/jacoco/testDebugUnitTest.exec")
    violationRules {
        failOnViolation = true
        rule {
            limit {
                minimum = 0.7
            }
        }
    }
}

We can execute it in commandline with:

./gradlew jacocoTestCoverageVerification

I used gradle wrapper 4.4.

JuanMoreno
  • 2,498
  • 1
  • 25
  • 34
  • Hi, really your explanation helped me a lot. Is there a way to test one particular class alone have the limit or not? – Rameshbabu Nov 06 '20 at 08:24
  • Yes, look at this question https://stackoverflow.com/questions/22505533/how-to-run-only-one-local-test-class-on-gradle – JuanMoreno Nov 12 '20 at 17:04
2

Gradle Jacoco Plugin by default will test Instruction coverage with below code:

jacocoTestCoverageVerification {
    violationRules {
        rule {
            limit {
                minimum = 0.85
            }
        }
    }
}

I had the requirement to test Line and Branch Coverage. In order to mention this to Jacoco, we will have to use Counter. Counter can have various values like: INSTRUCTION, LINE, BRANCH, COMPLEXITY, METHOD and CLASS. Instruction is the default one.

In order to validate both Line and branch coverage, one can use below code:

jacocoTestCoverageVerification {
    violationRules {
        rule {
            limit {
                counter = 'LINE'
                minimum = 0.87
            }
            limit {
                counter = 'BRANCH'
                minimum = 0.80
            }
        }
    }
}

One rule can contain multiple Limits.

Ref: https://docs.gradle.org/current/javadoc/org/gradle/testing/jacoco/tasks/rules/JacocoViolationRulesContainer.html

Dharman
  • 30,962
  • 25
  • 85
  • 135
mukesh210
  • 2,792
  • 2
  • 19
  • 41
2

This might help

Add plugins as below

plugins {
    id 'org.springframework.boot' version '2.7.3'
    id 'java'
    id 'jacoco'
}

Add jacoco version

jacoco {
    toolVersion = "0.8.8"
}

Add jacocoTestCoverageVerification task with minimum 80% coverage

jacocoTestCoverageVerification {
dependsOn test
enabled = true
violationRules {
    rule {
        limit {
            minimum = 0.5
        }
    }
    rule {
        element = 'CLASS'
        excludes = [
                'com.anypackage.*',
                'com.morepackage.*'
        ]
        limit {
            counter = 'CLASS'
            minimum = 0.8
        }
    }
}

}

to run jacocoTestCoverageVerification on every build

build.dependsOn jacocoTestCoverageVerification

Update test task

tasks.named('test') {
    useJUnitPlatform()
    finalizedBy jacocoTestCoverageVerification
}
Ali
  • 1,480
  • 2
  • 20
  • 30
0

Here is the compete Example

task wrapper(type: Wrapper){ 
     gradleVersion = '4.8' 
} 

plugins { 
    id 'java' 
    id 'maven' 
    id "jacoco" 
} 

jacoco{ 
    toolVersion = '0.8.1' 
} 

jacocoTestCoverageVerification { 
    violationRules { 
        rule { 
            limit { 
                minimum = 0.5 
            } 
        } 
    } 
} 


jacocoTestReport { 
     reports { 
        csv.enabled false 
        xml.enabled false 
        html { 
            enabled true 
            destination file("$buildDir/reports/jacoco") 
        } 
    } 
   executionData(test) 
} 

tasks.build.dependsOn(jacocoTestReport) 

test{ 
    jacoco{ 
        append = false 
        destinationFile = file("$buildDir/jacoco/jacocoTest.exec") 
        classDumpDir = file("$buildDir/jacoco/classpathdumps") 
    } 
} 
Ranjith Sekar
  • 1,892
  • 2
  • 14
  • 18