5

我试图将我的测试区分为单元测试和集成测试。我的想法是使用新的 JUnit5 Annotation @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 标签集成或其他分离单元测试和集成测试的想法有什么想法吗?

4

2 回答 2

4

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

免责声明:本指南适用于任何测试框架,不仅适用于Spek. Gradle 4.6或更新需要运行它。

将测试源集分离为源集

在我的示例中,它们将是:

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

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

完成后添加到以下行build.gradle之前:dependency 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"
}

设置执行顺序

我们需要添加 Test 类型的 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 {
    }
}

对 integrationTest 执行相同的操作。

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

// 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>.

其他资源:

于 2018-05-11T20:40:35.487 回答
0

使用 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
    }
}
于 2018-05-14T08:39:25.723 回答