Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xpepper/0119f0c20ff2b40918786e857873825a to your computer and use it in GitHub Desktop.
Save xpepper/0119f0c20ff2b40918786e857873825a to your computer and use it in GitHub Desktop.
Adding Jacoco code coverage measurement to a Kotlin Gradle project (and then adding coverage reports on a Jenkins pipeline)

Add code coverage to a gradle project

In order to have code coverage measurement enabled on your gradle project, you have to just add the jacoco plugin to the build.gradle plugin section

plugins {
    ...
    id 'jacoco'
}

When you now run ./gradlew test or other test tasks, you'll see that the build folder now contains a jacoco folder, with a *.exec type of file (e.g. test.exec).

build/
    classes
          kotlin
    jacoco
          test.exec
    ...          

This *.exec file contains a binary code coverage report of the test run. Nothing you can really read by yourself :-D

Fear not, for gradle is with you, giving you a couple of shiny new tasks:

  • jacocoTestReport => the most important: it generates a code coverage report (based on the last test run) in various formats (default is html)
  • jacocoTestCoverageVerification => it verifies code coverage metrics based on specified rules for the test task.

So, if you now run ./gradlew jacocoTestReport, a new folder will appear under build

build/
    classes
          kotlin
    jacoco
          test.exec
    reports
          jacoco

This reports/jacoco is where the html reports will be generated.

You can add more customizations to jacoco setup (e.g. have reports in other formats, like csv or xml, or generating reports in a different folder): see https://docs.gradle.org/current/userguide/jacoco_plugin.html to find all the details.

Publish code coverage reports in a Jenkins pipeline

This is where things start to become more fuzzy: the documentation is really not that clear, and all the examples on Internet (e.g. stackoverflow) are quite outdated. Anyway, to have the code coverage report published in your Jenkins job, just add somewhere, inside a step, the jacoco directive (no need to install special Jenkins plugins!).

The jacoco() directive has many sensitive defaults: chances are that those defaults will be fine for you (especially if the project is a classic Maven+Java project), but in case you have to tweak a bit the jacoco command, see the JaCoCo plugin Jenkins doc page to have all the options.

To give you a practical example, this is the jacoco directive of my Kotlin declarative pipeline:

// inside a step in the `Jenkinsfile`...
...
    jacoco(
        classPattern: '**/classes/kotlin/main',
        sourcePattern: '**/src/main/kotlin',
        sourceInclusionPattern: '**/*.kt'
    )
...    
  • classPattern selects just the kotlin application classes (no need to have code coverage on my tests :-D )
  • sourcePattern selects the location of the source files (again, just application files, no tests)
  • sourceInclusionPattern is needed because the default (at least on my version of the jacoco Jenkins plugin) would select only Java files ('**/*.java')

I put this jacoco command in the last post section of my declarative pipeline, where the artifacts are published and the build status notifications are sent. Other people prefer to put it just after the test execution... find the best thing for you and go for it. A good place to make up your mind is this post.

Again, to make a practical example:

post {
    always {
        archiveArtifacts artifacts: '**/build/libs/*.war', onlyIfSuccessful: true
        jacoco(
            classPattern: '**/classes/kotlin/main',
            sourcePattern: '**/src/main/kotlin',
            sourceInclusionPattern: '**/*.kt'
        )
    }
    success {
        slackSend(
            channel: "3ds_2_issuer",
            color: 'good',
            message: "*${env.JOB_NAME}* #${env.BUILD_NUMBER} passed (${env.BUILD_URL}) :thumbsup:"
        )
    }
    ...

That's it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment