Gradle Jacoco and JUnit5

。_饼干妹妹 提交于 2019-12-03 11:11:36

问题


We just ported our unit tests to JUnit5. Realizing that this is still rather early adoption with little hints on google.

The most challenging was to get jacoco code coverage for the Junit5 tests which we use on jenkins. Since this took me almost a day to figure out, I thought I share. Nevertheless, if you know of a better solution I would be interested to know!

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'

Then the problem seems to be that junitPlatformTest as defined in the org.junit.platform.gradle.plugin is defined too late in the gradle lifecycle phase and hence is unknown when the script is parsed.

The following hack is needed in order to still be able to define a jacoco task which observes the junitPlatformTest task.

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
            })
    }
}

Finally it is necessary to configure the junitPlatform plugin. The following code allows command line configuration of which junit 5 tags shall be run: You can run all tests with 'unit' tag by running:

gradle clean junitPlatformTest -PincludeTags=unit

You can run all tests which are missing both unit and integ tag using

gradle clean junitPlatformTest -PexcludeTags=unit,integ

If no tags are provided all tests will be run (default).

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
}

回答1:


Thank you, so the hack now looks like this:

project.afterEvaluate {
    def junitPlatformTestTask = project.tasks.getByName('junitPlatformTest')

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

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



回答2:


Can be also resolved with direct agent injection:

subprojects {
   apply plugin: 'jacoco'

   jacoco {
        toolVersion = "0.7.9"
   }

   configurations {
        testAgent {
            transitive = false
        }
   }

   dependencies {
        testAgent("org.jacoco:org.jacoco.agent:0.7.9:runtime")
   }

   tasks.withType(JavaExec) {
        if (it.name == 'junitPlatformTest') {
            doFirst {
                jvmArgs "-javaagent:${configurations.testAgent.singleFile}=destfile=${project.buildDir.name}/jacoco/test.exec"
            }
        }
    }
}

then report will be available with jacocoTestReport task




回答3:


To get a reference to the junitPlatformTest task, another option is to implement an afterEvaluate block in the project like this:

afterEvaluate {
  def junitPlatformTestTask = tasks.getByName('junitPlatformTest')

  // do something with the junitPlatformTestTask
}

See my comments on GitHub for JUnit 5 for further examples.




回答4:


You just need to add @RunWith(JUnitPlatform.class) to your package

@RunWith(JUnitPlatform.class)
public class ClassTest {
}


来源:https://stackoverflow.com/questions/39362955/gradle-jacoco-and-junit5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!