使用 JUnit5 标签进行 Spek



我正在尝试将我的测试区分为单元测试和集成测试。 我的想法是使用新的JUnit5注释@Tag("unit")它非常适合我的JUnit测试,但我无法让它与Spek一起使用。

我目前拥有的是我的班级:

data class MyObject(val value: Int)

我的测试:

@Tag("unit")
object MyObjectTest {
@Test
fun checkEquality() {
val o1 = MyObject(1)
assertEquals(o1, o1)
}
}

随着我的build.gradle有:

task utest(type: Test) {
outputs.upToDateWhen { false }
useJUnitPlatform {
includeEngines 'junit-jupiter', 'junit-vintage', 'spek'
includeTags 'unit'
excludeTags 'performance', 'integration', 'functional'
}

testLogging {
events "passed", "skipped", "failed"
}
}

当我执行 utest 时,这有效。 但是,当对 Spek 执行相同操作时:

@Tag("unit")
object MyObjectSpek : Spek({
given("an Object") {
val o1 = MyObject(1)
it("should be equal to itself") {
assertEquals(o1, o1)
}
}
})

发生的情况是,如果我运行 gradle 任务 utest,它只执行MyObjectTest中的方法,而不执行MyObjectSpek

关于如何将 Spek 与 JUnit5 标签集成或其他想法以分离单元测试和集成测试的任何想法?

今天我遇到了同样的问题。我不得不将测试分为 3 个部分:单元、服务(测试 REST API(和集成(WebDriver(。

声明者:本指南适用于任何测试框架,不仅适用于Spek。 运行此命令需要Gradle 4.6或更高版本。

将测试源集分离到源集中

在我的示例中,它们是:

  • src/test— 用于单元测试(您已经拥有它(
  • src/serviceTest— 用于服务测试
  • src/integrationTest— 用于集成测试

所有这些集都应该具有标准的源集结构。在项目中创建这些文件夹,并将包移动到相应的源集。

完成后,在以下行之前添加到build.gradledependency section

sourceSets {
integrationTest {
compileClasspath += main.output
runtimeClasspath += main.output
}
serviceTest {
compileClasspath += main.output
runtimeClasspath += main.output
}
}
configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
serviceTestCompile.extendsFrom testCompile
serviceTestRuntime.extendsFrom testRuntime
}

执行此操作后,您的IDE(我想您使用Idea(应该重新索引build.gradle并识别源代码集。新源集中可能存在错误,因为它们看不到彼此的源。这是正确的,因为这些源集旨在独立运行,应该不是问题。

dependencies与适当的配置分开(可选(

默认情况下,serviceTestintegrationTest继承所有test依赖项,但如果您需要将特定于特定配置的内容移出公共范围,则可以在此处执行此操作。

就我而言,WebDriver非常重,除了集成测试之外,我在任何地方都不需要它。

dependencies {
// available for all scopes
testCompile "org.jetbrains.spek:spek-api:$spekVersion"
testRuntime "org.jetbrains.spek:spek-junit-platform-engine:$spekVersion"
testCompile "org.junit.platform:junit-platform-launcher:$junitPlatformVersion"
// compiles only for integrationTest
integrationTestCompile "org.seleniumhq.selenium:selenium-java:3.11.0"
integrationTestCompile "org.seleniumhq.selenium.fluent:fluent-selenium:1.19"
}

设置执行顺序

我们需要添加测试类型的 gradle 任务并对其进行设置。您可以为不同的测试任务设置不同的设置。

task serviceTest(type: Test) {
// Runs tests from src/serviceTest
testClassesDirs = sourceSets.serviceTest.output.classesDirs
classpath = sourceSets.serviceTest.runtimeClasspath
}
// Setup serviceTest task 
serviceTest {
// Uncomment this if you need to skip tests from the set after first failure. Since Gradle 4.6
//failFast = true
// Enable some logging
testLogging {
events "PASSED", "FAILED", "SKIPPED"
}
// Enable JUnit5 tests
useJUnitPlatform {
}
}

对集成测试执行相同的操作。

最后,设置依赖项和执行顺序:

// Make service tests run during gradle check
check.dependsOn serviceTest
check.dependsOn integrationTest
// Make service tests run after unit tests
serviceTest.mustRunAfter test
// Make integration tests run after service tests
integrationTest.mustRunAfter serviceTest

结论

您将获得:

  1. 严格顺序运行的Unit -> Service -> Integration测试套件链;
  2. 如果您在一个测试套件中遇到测试失败(无论failFast选项如何(,其余测试套件将不会运行并浪费资源;
  3. 能够在执行gradle <task>内从控制台单独运行每个套件。

其他资源:

  • 下面是使用Spek实现此设置的示例build.gradle
  • gradle 4.6 版本的发行说明介绍了许多与测试相关的东西。

使用 IntelliJ 时要考虑的另一件事,并且它与新源代码集存在依赖问题,请将其添加到您的 build.gradle 中:

apply plugin: 'idea'
idea {
module {
testSourceDirs += project.sourceSets.unitTest.kotlin.srcDirs
testSourceDirs += project.sourceSets.unitTest.resources.srcDirs
testSourceDirs += project.sourceSets.integrationTest.kotlin.srcDirs
testSourceDirs += project.sourceSets.integrationTest.resources.srcDirs
testSourceDirs += project.sourceSets.functionalTest.kotlin.srcDirs
testSourceDirs += project.sourceSets.functionalTest.resources.srcDirs
}
}

相关内容

  • 没有找到相关文章

最新更新