Gradle Jacoco e JUnit5

Acabamos de portar nossos testes de unidade para o JUnit5. Percebendo que essa ainda é uma adoção bastante precoce, com poucas dicas no google.

O mais desafiador foi obter cobertura de código jacoco para os testes Junit5 que usamos nos jenkins. Como isso me levou quase um dia para descobrir, pensei em compartilhar. No entanto, se você souber de uma solução melhor, eu estaria interessado em saber!

buildscript {

    dependencies {
       // dependency needed to run junit 5 tests
       classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-M2'
   }
}

// include the jacoco plugin
plugins {
    id 'jacoco'
}

dependencies {
    testCompile "org.junit.jupiter:junit-jupiter-api:5.0.0-M2"
    runtime "org.junit.jupiter:junit-jupiter-engine:5.0.0-M2"
    runtime "org.junit.vintage:junit-vintage-engine:4.12.0-M2"
}

apply plugin: 'org.junit.platform.gradle.plugin'

Parece que o problema é que junitPlatformTest, conforme definido no org.junit.platform.gradle.plugin, é definido muito tarde na fase do ciclo de vida do gradle e, portanto, é desconhecido quando o script é analisado.

O seguinte hack é necessário para que ainda seja possível definir uma tarefa jacoco que observe a tarefa junitPlatformTest.

tasks.whenTaskAdded { task ->
    if (task.name.equals('junitPlatformTest')) {
        System.out.println("ADDING TASK " + task.getName() + " to the project!")

    // configure jacoco to analyze the junitPlatformTest task
    jacoco {
        // this tool version is compatible with
        toolVersion = "0.7.6.201602180812"
        applyTo task
    }

    // create junit platform jacoco task
    project.task(type: JacocoReport, "junitPlatformJacocoReport",
            {
                sourceDirectories = files("./src/main")
                classDirectories = files("$buildDir/classes/main")
                executionData task
            })
    }
}

Finalmente, é necessário configurar o plug-in junitPlatform. O código a seguir permite a configuração da linha de comando com as tags 5 de junho que devem ser executadas: Você pode executar todos os testes com a tag 'unit' executando:

gradle clean junitPlatformTest -PincludeTags=unit

Você pode executar todos os testes que estão faltando as tags unit e integ usando

gradle clean junitPlatformTest -PexcludeTags=unit,integ

Se nenhuma tag for fornecida, todos os testes serão executados (padrão).

junitPlatform {

    engines {
        include 'junit-jupiter'
        include 'junit-vintage'
    }

    reportsDir = file("$buildDir/test-results")

    tags {
        if (project.hasProperty('includeTags')) {
            for (String t : includeTags.split(',')) {
                include t
            }
        }

        if (project.hasProperty('excludeTags')) {
            for (String t : excludeTags.split(',')) {
                exclude t
            }
        }
    }

    enableStandardTestTask false
}

questionAnswers(4)

yourAnswerToTheQuestion