在 spring 引导应用程序中分离集成测试
Separating integration tests in spring boot app
我正在为 SpringBoot 应用程序编写测试。
我想将集成测试与单元测试分开。
现在我的项目结构看起来像这样:
├── Demo
│ ├── src
│ │ ├── main
| | | └──java
│ │ ├── test
| | | └──java
有没有办法添加这样的模块:
├── Demo
│ ├── src
│ │ ├── main
| | | └──java
│ │ ├── integrationTest
| | | └──java
│ │ ├── test
| | | └──java
我希望新的 integrationTest 模块能像测试模块一样工作,但我不知道如何配置它。我设法将它添加为模块,将 integrationTest/java 目录标记为 Test Sources Root 并在其中进行 运行 测试,但 @SpringBootTest 无法解析 ApplicationContext,并且我的所有 bean 始终为空。
当我在测试模块中编写相同的测试时,它工作正常。
有办法吗?
这是分离集成测试的正确方法吗?
如果不是,最佳做法是什么?
我在 intelliJ 工作,我使用 gradle 作为包管理器。
您可以将它们与其余测试一起使用;应用 约定 和标签匹配以过滤掉它们,例如将 IntegrationTest
附加到 class 名称并为 JUnit 使用相同的值@Tag
...然后 define/declare 一些 Gradle 任务来执行它们:
test {
useJUnitPlatform()
}
task integrationTests(type: Test) {
filter { includes = ["IntegrationTest"] }
useJUnitPlatform()
}
task unitTests(type: Test) {
filter { includes = ["UnitTest"] }
useJUnitPlatform()
}
完整示例:
package tld.domain.support;
public final class Category {
public static final INTEGRATION_TEST = "IntegrationTest";
public static final UNIT_TEST = "UnitTest";
}
import tld.domain.support.Category;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Tag(Category.INTEGRATION_TEST)
final class MyIntegrationTest {
@Test
void testFoo() {
// ...
}
根据@iboisver 的评论,您可以将它们分开,我们鼓励您在 gradle docs 中这样做。您基本上必须:
- 在
src
下创建一个新目录(即 src/integrationTest
)
- 在
build.gradle
文件中添加源集及其配置:
sourceSets {
integrationTest {
compileClasspath += sourceSets.main.output + sourceSets.test.output
runtimeClasspath += sourceSets.main.output + sourceSets.test.output
}
}
configurations {
integrationTestImplementation.extendsFrom testImplementation
integrationTestRuntimeOnly.extendsFrom testRuntime
}
- 为 运行 集成测试创建一个
integrationTests
任务,并将其附加到 check
任务(也在 build.gradle
中):
task integrationTest(type: Test) {
description = 'Runs integration tests.'
group = 'verification'
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
shouldRunAfter test
}
check.dependsOn integrationTest
我找到了几篇非常有用的文章 (1, 2),它们指导我进行自己的集成测试设置。
注意:如果您使用 JVM Test Suite Plugin(需要 Gradle 7.3+),整个过程似乎要简单得多,但由于它处于孵化状态,我没有接受它。
我正在为 SpringBoot 应用程序编写测试。 我想将集成测试与单元测试分开。 现在我的项目结构看起来像这样:
├── Demo
│ ├── src
│ │ ├── main
| | | └──java
│ │ ├── test
| | | └──java
有没有办法添加这样的模块:
├── Demo
│ ├── src
│ │ ├── main
| | | └──java
│ │ ├── integrationTest
| | | └──java
│ │ ├── test
| | | └──java
我希望新的 integrationTest 模块能像测试模块一样工作,但我不知道如何配置它。我设法将它添加为模块,将 integrationTest/java 目录标记为 Test Sources Root 并在其中进行 运行 测试,但 @SpringBootTest 无法解析 ApplicationContext,并且我的所有 bean 始终为空。
当我在测试模块中编写相同的测试时,它工作正常。
有办法吗? 这是分离集成测试的正确方法吗? 如果不是,最佳做法是什么?
我在 intelliJ 工作,我使用 gradle 作为包管理器。
您可以将它们与其余测试一起使用;应用 约定 和标签匹配以过滤掉它们,例如将 IntegrationTest
附加到 class 名称并为 JUnit 使用相同的值@Tag
...然后 define/declare 一些 Gradle 任务来执行它们:
test {
useJUnitPlatform()
}
task integrationTests(type: Test) {
filter { includes = ["IntegrationTest"] }
useJUnitPlatform()
}
task unitTests(type: Test) {
filter { includes = ["UnitTest"] }
useJUnitPlatform()
}
完整示例:
package tld.domain.support;
public final class Category {
public static final INTEGRATION_TEST = "IntegrationTest";
public static final UNIT_TEST = "UnitTest";
}
import tld.domain.support.Category;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Tag(Category.INTEGRATION_TEST)
final class MyIntegrationTest {
@Test
void testFoo() {
// ...
}
根据@iboisver 的评论,您可以将它们分开,我们鼓励您在 gradle docs 中这样做。您基本上必须:
- 在
src
下创建一个新目录(即src/integrationTest
) - 在
build.gradle
文件中添加源集及其配置:
sourceSets {
integrationTest {
compileClasspath += sourceSets.main.output + sourceSets.test.output
runtimeClasspath += sourceSets.main.output + sourceSets.test.output
}
}
configurations {
integrationTestImplementation.extendsFrom testImplementation
integrationTestRuntimeOnly.extendsFrom testRuntime
}
- 为 运行 集成测试创建一个
integrationTests
任务,并将其附加到check
任务(也在build.gradle
中):
task integrationTest(type: Test) {
description = 'Runs integration tests.'
group = 'verification'
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
shouldRunAfter test
}
check.dependsOn integrationTest
我找到了几篇非常有用的文章 (1, 2),它们指导我进行自己的集成测试设置。
注意:如果您使用 JVM Test Suite Plugin(需要 Gradle 7.3+),整个过程似乎要简单得多,但由于它处于孵化状态,我没有接受它。