【问题标题】:Gradle Jacoco and JUnit5Gradle Jacoco 和 JUnit5
【发布时间】:2017-01-14 17:37:58
【问题描述】:

我们刚刚将单元测试移植到了 JUnit5。意识到这仍然是相当早的采用,在谷歌上几乎没有任何提示。

最具挑战性的是为我们在 jenkins 上使用的 Junit5 测试获取 jacoco 代码覆盖率。因为这花了我将近一天的时间才弄清楚,所以我想我分享一下。不过,如果您知道更好的解决方案,我很想知道!

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'

那么问题似乎是在 org.junit.platform.gradle.plugin 中定义的 junitPlatformTest 也被定义了 在 gradle 生命周期阶段的后期,因此在解析脚本时是未知的。

为了仍然能够定义一个观察 junitPlatformTest 任务的 jacoco 任务,需要以下 hack。

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

最后需要配置junitPlatform插件。以下代码允许命令行配置应运行哪些 junit 5 标签: 你可以通过运行来运行所有带有“unit”标签的测试:

gradle clean junitPlatformTest -PincludeTags=unit

您可以使用

运行所有缺少单元和整数标记的测试
gradle clean junitPlatformTest -PexcludeTags=unit,integ

如果没有提供标签,所有测试都将运行(默认)。

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
}

【问题讨论】:

  • 我投票决定将此问题作为离题结束,因为它是一个解决方案而不是一个问题
  • 如果分成问题和答案就好了。
  • 我同意@PaulHicks 的观点,即这应该是一个自我回答的问题。您可以查看文档here。此外,“Gradle 生命周期中为时已晚”的问题应该是 fixed in M5
  • 如果我昨天找到它,这对我来说真的很有用!幸运的是,其他人帮助我获得了相同的信息。

标签: jenkins gradle jacoco junit5


【解决方案1】:

谢谢,现在的 hack 看起来像这样:

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】:

    也可以通过直接代理注入来解决:

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

    然后报告将与jacocoTestReport 任务一起提供

    【讨论】:

      【解决方案3】:

      要获得对junitPlatformTest 任务的引用,另一种选择是在项目中实现afterEvaluate 块,如下所示:

      afterEvaluate {
        def junitPlatformTestTask = tasks.getByName('junitPlatformTest')
      
        // do something with the junitPlatformTestTask
      }
      

      有关更多示例,请在 GitHub for JUnit 5 上查看我的 cmets。

      【讨论】:

        【解决方案4】:

        您只需将@RunWith(JUnitPlatform.class) 添加到您的包中

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

        【讨论】:

          猜你喜欢
          • 2018-02-24
          • 1970-01-01
          • 2018-01-09
          • 2019-08-11
          • 2016-09-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-20
          相关资源
          最近更新 更多