使用Gradle Kotlin DSL进行集成测试

我正在使用 this blog post为Spring Boot项目配置集成测试,但我非常坚持声明源集.我也找到了 this post on StackOverflow,但我想我已经进一步了.

我的项目结构是

project
|_ src
  |_ main
  | |_ kotlin
  | |_ resources
  |_ testIntegration
  | |_ kotlin
  | |_ resources
  |_ test
  | |_ kotlin
  | |_ resources
  |_ build.gradle.kts
  |_ ... other files

和build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    idea
    kotlin("jvm")
    id("org.springframework.boot") version "2.0.5.RELEASE"
    id("org.jetbrains.kotlin.plugin.spring") version "1.2.71"
}

fun DependencyHandlerScope.springBoot(module: String) = this.compile("org.springframework.boot:spring-boot-$module:2.0.5.RELEASE")
fun DependencyHandlerScope.springBootStarter(module: String) = this.springBoot("starter-$module")

dependencies {
    springBoot("devtools")

    springBootStarter("batch")
    springBootStarter("... spring boot dependencies")


    compile("... more dependencies")

    testCompile("... more test dependencies")
}

val test by tasks.getting(Test::class) {
    useJUnitPlatform { }
}

kotlin {
    sourceSets {
        val integrationTest by creating {
            kotlin.srcDir("src/testIntegration/kotlin")
            resources.srcDir("src/testIntegration/resources")
        }
    }
}

val integrationTestCompile by configurations.creating {
    extendsFrom(configurations["testCompile"])
}
val integrationTestRuntime by configurations.creating {
    extendsFrom(configurations["testRuntime"])
}

val testIntegration by tasks.creating(Test::class) {
    group = "verification"
    testClassesDirs = kotlin.sourceSets["integrationTest"].kotlin
}

idea {
    module {
        testSourceDirs.addAll(kotlin.sourceSets["integrationTest"].kotlin.srcDirs)
        testSourceDirs.addAll(kotlin.sourceSets["integrationTest"].resources.srcDirs)
    }
}

我想我的方向非常正确.至少它不再抛出异常:)

当我运行testIntegration任务时,我得到以下输出:

Testing started at 12:08 ...
12:08:49: Executing task 'testIntegration'...

> Task :project:compileKotlin UP-TO-DATE
> Task :project:compileJava NO-SOURCE
> Task :project:processResources UP-TO-DATE
> Task :project:classes UP-TO-DATE
> Task :project:compileTestKotlin UP-TO-DATE
> Task :project:compileTestJava NO-SOURCE
> Task :project:processTestResources UP-TO-DATE
> Task :project:testClasses UP-TO-DATE
> Task :project:testIntegration
BUILD SUCCESSFUL in 2s
5 actionable tasks: 1 executed, 4 up-to-date
12:08:51: Task execution finished 'testIntegration'.

此外,IntelliJ不会将testIntegration目录识别为Kotlin包.

感谢Kotlin Slack频道的一些帮助,我终于弄明白了.首先,我必须升级到Gradle版本4.10.2.

有关更多信息,请查看Gradle的这两个页面:

> https://docs.gradle.org/release-nightly/userguide/organizing_gradle_projects.html#sec:separate_test_type_source_files
> https://docs.gradle.org/release-nightly/userguide/organizing_gradle_projects.html#sec:separate_test_type_source_files

然后我只需要为integrationTests创建sourceSets

sourceSets {
    create("integrationTest") {
            kotlin.srcDir("src/integrationTest/kotlin")
            resources.srcDir("src/integrationTest/resources")
            compileClasspath += sourceSets["main"].output + configurations["testRuntimeClasspath"]
            runtimeClasspath += output + compileClasspath + sourceSets["test"].runtimeClasspath
    }
}

这对Java来说效果很好,但由于我正在使用Kotlin,我必须添加一个额外的withConvention包装器

sourceSets {
    create("integrationTest") {
        withConvention(KotlinSourceSet::class) {
            kotlin.srcDir("src/integrationTest/kotlin")
            resources.srcDir("src/integrationTest/resources")
            compileClasspath += sourceSets["main"].output + configurations["testRuntimeClasspath"]
            runtimeClasspath += output + compileClasspath + sourceSets["test"].runtimeClasspath
        }
    }
}

在docs中他们只放了runtimeClasspath = output compileClasspath,但是我添加了sourceSets [“test”].runtimeClasspath所以我可以直接使用测试依赖项而不是为integrationTest任务声明新的依赖项.

一旦创建了sourceSets,就需要声明一个新任务

task<Test>("integrationTest") {
    description = "Runs the integration tests"
    group = "verification"
    testClassesDirs = sourceSets["integrationTest"].output.classesDirs
    classpath = sourceSets["integrationTest"].runtimeClasspath
    mustRunAfter(tasks["test"])
}

在此之后测试仍然没有运行,但那是因为我正在使用JUnit4.所以我只需要添加useJUnitPlatform(),这使得它成为最终的代码

task<Test>("integrationTest") {
    description = "Runs the integration tests"
    group = "verification"
    testClassesDirs = sourceSets["integrationTest"].output.classesDirs
    classpath = sourceSets["integrationTest"].runtimeClasspath
    mustRunAfter(tasks["test"])
    useJUnitPlatform()
}
相关文章
相关标签/搜索