在 Spring Boot 应用程序中分离集成测试
Posted
技术标签:
【中文标题】在 Spring Boot 应用程序中分离集成测试【英文标题】:Separating integration tests in spring boot app 【发布时间】:2020-04-29 20:18:27 【问题描述】:我正在为 SpringBoot 应用程序编写测试。 我想将集成测试与单元测试分开。 现在我的项目结构如下所示:
├── Demo
│ ├── src
│ │ ├── main
| | | └──java
│ │ ├── test
| | | └──java
有没有办法像这样添加模块:
├── Demo
│ ├── src
│ │ ├── main
| | | └──java
│ │ ├── integrationTest
| | | └──java
│ │ ├── test
| | | └──java
我希望新的 integrationTest 模块与测试模块相同,但我不知道如何配置它。我设法将它添加为模块,将 integrationTest/java 目录标记为测试源根目录并在其中运行测试,但 @SpringBootTest 无法解析 ApplicationContext,并且我所有的 bean 始终为空。
当我在测试模块中编写相同的测试时,它工作正常。
有没有办法做到这一点? 这是分离集成测试的正确方法吗? 如果不是,最佳做法是什么?
我在 intelliJ 工作,我使用 gradle 作为包管理器。
【问题讨论】:
Gradle 用户手册有一节描述了如何做到这一点docs.gradle.org/current/userguide/…>。您可以使用systemProperty("spring.profiles.active", "integration")
之类的东西在 integrationTest 任务定义中设置活动配置文件,尽管我猜如果集成和单元测试源是分开的,您实际上并不需要。感谢 baeldung.com/spring-profiles> 提到要设置的系统属性。
【参考方案1】:
您可以在其余测试中使用它们;应用 convention 并标记匹配以将它们过滤掉,例如将 IntegrationTest
附加到类名并为 JUnit @Tag
使用相同的值...然后只需定义/声明一些 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()
// ...
【讨论】:
【参考方案2】:基于@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+),整个过程似乎要简单得多,但由于它处于孵化状态,我没有使用它。
【讨论】:
以上是关于在 Spring Boot 应用程序中分离集成测试的主要内容,如果未能解决你的问题,请参考以下文章
如何从 springboot 应用程序中分离集成的 tomcat
如何使用注释在 testng + maven 中分离单元测试和集成测试?