Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle Jacoco plugin not generating reports

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:

  1. It excludes my com.me.myapp.domain.model package and all of its contents; and
  2. It fails my build if code coverage on the non-excluded classes falls below 70%; and
  3. Pass or fail, I want an HTML version of the Jacoco report generated under the build/ directory; and
  4. 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?

like image 340
hotmeatballsoup Avatar asked Jul 10 '18 14:07

hotmeatballsoup


People also ask

How do I get my JaCoCo report?

For generating JaCoCo reports only run the maven build with profile jacoco-generate-report as it is shown in the example above. After the command was executed, in directory target/jacoco-report you can find reports in HTML and XML formats.

Why does JaCoCo not show coverage?

Why does the coverage report not show line coverage figures? JaCoCo is based on class files analysis. To calculate line coverage class files must contain line number attributes. For this your code must be compiled with debug information.

What is jacocoTestReport?

JaCoCo Report configuration The JacocoReport task can be used to generate code coverage reports in different formats. It implements the standard Gradle type Reporting and exposes a report container of type JacocoReportsContainer.


1 Answers

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 the check 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
like image 74
Lukas Körfer Avatar answered Sep 21 '22 18:09

Lukas Körfer