JUnit5标签特定的Gradle任务

40

我使用以下注释来标记我的集成测试:

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Tag("integration-test")
public @interface IntegrationTest {
}

这是我在build.gradle中使用的筛选器,用于将这些测试排除在gradle build之外:

junitPlatform {
    filters {
        tags {
            exclude 'integration-test'
        }
    }
}

到目前为止,一切都很好。

现在我想提供一个Gradle任务,专门运行我的集成测试 - 有什么推荐的方法吗?


这是一个非常好的问题,但很遗憾目前由于我们实现JUnit平台Gradle插件的方式,没有一个“干净”的解决方案。因此,您是否愿意创建一个问题,以便我们将其保留在我们的视线中?https://github.com/junit-team/junit5/issues/new - Sam Brannen
感谢您的反馈!https://github.com/junit-team/junit5/issues/579 - Rahel Lüthy
5个回答

65

基于 https://github.com/gradle/gradle/issues/6172#issuecomment-409883128

已在2020年进行修订以考虑懒加载任务配置和Gradle 5。有关旧版本,请参见答案历史记录。

plugins {
    id "java"
}

def test = tasks.named("test") {
    useJUnitPlatform {
        excludeTags "integration"
    }
}

def integrationTest = tasks.register("integrationTest2", Test) {
    useJUnitPlatform {
        includeTags "integration"
    }
    shouldRunAfter test
}

tasks.named("check") {
    dependsOn integrationTest
}

运行

  • gradlew test 将仅运行测试,不包括集成测试
  • gradlew integrationTest 仅会运行集成测试
  • gradlew check 将运行test 然后是 integrationTest
  • gradlew integrationTest test 将运行test 然后是 integrationTest
    注意: 顺序被交换了,因为 shouldRunAfter

历史

提示

注意:虽然上述内容可行,但 IntelliJ IDEA 很难推断信息,所以我建议使用这个更明确的版本,其中所有内容都是已输入并支持代码补全:

... { Test task ->
    task.useJUnitPlatform { org.gradle.api.tasks.testing.junitplatform.JUnitPlatformOptions options ->
        options.includeTags 'integration'
    }
}

build.gradle.kts

这是一个用于在Gradle 5.6.4中配置所有模块集成测试的根项目 Kotlin DSL 插件。

allprojects {
    plugins.withId("java") {
        @Suppress("UnstableApiUsage")
        this@allprojects.tasks {
            val test = "test"(Test::class) {
                useJUnitPlatform {
                    excludeTags("integration")
                }
            }
            val integrationTest = register<Test>("integrationTest") {
                useJUnitPlatform {
                    includeTags("integration")
                }
                shouldRunAfter(test)
            }
            "check" {
                dependsOn(integrationTest)
            }
        }
    }
}

13

Gradle 6

我不确定是因为Gradle的行为发生了变化,但是在Gradle 6.8.3中,得分最高的答案对我没有起作用。我看到integrationTests任务与主测试任务一起运行。这个简化版本对我有用:

test {
    useJUnitPlatform {
        excludeTags "integration"
    }
}

tasks.register("integrationTests", Test) {
    useJUnitPlatform {
        includeTags "integration"
    }
    mustRunAfter check
}

命令:

  • ./gradlew test./gradlew clean build - 运行没有“integration”标签的测试。
  • ./gradlew integrationTests - 仅运行带有“integration”标签的测试。

完全同意。高票答案对我没用,但标记是个好主意。它很有效。 - divspec

12

我提交了一个问题:https://github.com/junit-team/junit5/issues/579 (遵循 Sam Brannen 的建议)。

同时,我正在使用一个项目属性作为解决方法:

junitPlatform {
    filters {
        tags {
            exclude project.hasProperty('runIntegrationTests') ? '' : 'integration-test'
        }
    }
}

因此,使用以下命令:

gradle test

跳过集成测试。

但是,如果想要包括集成测试,则需要使用以下命令:

gradle test -PrunIntegrationTests


1
太棒了!我本来也想建议一个类似的解决方法。所以很高兴你自己找到了答案。另外,感谢你提出 GitHub 的问题。 - Sam Brannen

1

在编程中,可以采用类似Rahel Lüthy的方法来避免使用空字符串,这种方法可以运行所有测试或只运行一些标签:

test {
    useJUnitPlatform() {
        if (project.hasProperty("includes")) {
            includeTags(project.property("includes") as String)
        }
    }
}

0

据我所知,目前解决这个问题的最佳工作代码是由TWiStErRob提供的这里

请注意,在下面的示例中,测试必须使用ui标记(Junit5标记):

task uiTest(type: Test) {
    useJUnitPlatform {
        includeTags 'ui'
        excludeTags 'integration'
    }
}

然而,我没有成功地让Junit5 test-suit-thing直接从gradle运行,我认为这将是一个更好的解决方案。但我认为TWiStErRob的解决方案已经足够好了。缺点是gradle.build文件现在也会被测试套件填满。

请注意,像这样在gradle文件中创建多个测试套件是可以的:

task firstTestSuite(type: Test) {
    useJUnitPlatform {
        includeTags 'test-for-first-test-suite'
    }
}

task secondTestSuite(type: Test) {
    useJUnitPlatform {
        includeTags 'test-for-second-test-suite'
    }
}

然后,所有内容都可以单独运行,就像这样:

gradlew firstTestSuite
gradlew secondTestSuite
gradlew ui

该解决方案使用Gradle 6.6.1运行


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接