Gradle Jacoco 和 JUnit5
Posted
技术标签:
【中文标题】Gradle Jacoco 和 JUnit5【英文标题】:Gradle Jacoco and 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。 如果我昨天找到它,这对我来说真的很有用!幸运的是,其他人帮助我获得了相同的信息。 【参考方案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
【讨论】:
以上是关于Gradle Jacoco 和 JUnit5的主要内容,如果未能解决你的问题,请参考以下文章
使用 Sonarrunner 和 Gradle 从 Jacoco 报告中排除包
使用Sonarrunner和Gradle从Jacoco报告中排除软件包
在没有 Maven 或 Gradle 的情况下运行 jacoco 报告