仅在设置了特定的弹簧配置文件时才运行集成测试

Posted

技术标签:

【中文标题】仅在设置了特定的弹簧配置文件时才运行集成测试【英文标题】:Run integration tests only if specific spring profile is set 【发布时间】:2019-04-18 15:07:24 【问题描述】:

我们的 Spring Boot 应用程序中有多个测试类。一些类包含集成测试,一些包含单元测试。 这意味着如果我(例如使用 maven)让所有测试都被执行,它将运行所有类中的所有测试。

我想要实现的是,只有在设置了特定的弹簧配置文件时才执行集成测试,例如通过 application.yml。 我喜欢例如注释整个测试类以定义该类中的测试仅在设置了指定的弹簧配置文件时才执行。 如果未设置,则应忽略这些测试。

主题How can I use @IfProfileValue to test if a Profile is active? 正是朝着这个方向发展。 @IfProfileValue 乍一看就像我需要的一样。 但正如它所指出的,事实并非如此。如果我要设置特定的系统属性,我可以使用它。但我需要使用真正的弹簧配置文件(而不是系统属性spring.profiles.active - 这将忽略通过application.yml 设置的配置文件) @Profile 似乎也是我需要的,但正如主题 Use @Profile to decide to execute test class 所示,我们不应该使用它。

那么可以做些什么来实现这一点呢? 请注意,关于堆栈溢出的测试和弹簧配置文件有很多问题。但是他们中的大多数都指出了如何在特定于弹簧配置文件的测试中设置配置。那不是我要找的。 我想执行或忽略测试。

【问题讨论】:

使用 surefire 进行单元测试,使用 Failsafe 进行集成测试。单元测试以 *Test.java 结束,集成测试以 *IT.java/*ITCase.java 结束,然后您可以设置配置文件来执行它。 【参考方案1】:

我不确切知道你想如何实现它,但如果你使用 junit 在运行时有条件地忽略一些测试,只需使用配置属性,这是一种方法:

application.properties:

test.enabled=true

然后在您的测试代码中,您可以使用org.junit.Assume 和如下属性:

@Value("$test.enabled")
private Boolean testEnabled;

@Test
public void test 
    org.junit.Assume.assumeTrue(testEnabled);
    // your test code

现在,如果您将属性 test.enabled 设置为 true,则测试将运行,否则将被忽略。

来源:Conditionally ignoring tests in JUnit 4

【讨论】:

我认为这仍然会启动整个 spring 应用程序上下文,其中 ime 通常是大部分时间吃的,而不是测试本身【参考方案2】:

使用 JUnit 5,您可以使用 @Autowired Environment 来检查配置文件是否处于活动状态 @BeforeEach 测试运行: Assumptions.assumeTrue(Arrays.asList(this.environment.getActiveProfiles()).contains("integration"));

这会检查名为“集成”的配置文件,并且无论配置文件的设置方式如何(系统属性、环境变量、application.yml 等)都有效。

如果配置文件未激活,则测试将被忽略,这类似于使用@Disabled 注解。

【讨论】:

【参考方案3】:

这很容易。我在 kotlin 中的解决方案:

    创建annotation
import org.springframework.test.context.junit.jupiter.EnabledIf
import kotlin.annotation.AnnotationRetention.RUNTIME
import kotlin.annotation.AnnotationTarget.CLASS
import kotlin.annotation.AnnotationTarget.FUNCTION

@Target(CLASS, FUNCTION)
@Retention(RUNTIME)
@EnabledIf(
    expression = "#environment.acceptsProfiles('integration')",
    reason = "??‍ Because spring.profiles.active = integration",
    loadContext = true)
annotation class Integration
    使用它:
import by.package.Integration


@Integration
internal class IntegrationTest 

    @Test
    // @Integration 
    fun test() 
       assertEquals(4, 2 + 2)
    

@DisableIf注解逻辑相反

【讨论】:

以上是关于仅在设置了特定的弹簧配置文件时才运行集成测试的主要内容,如果未能解决你的问题,请参考以下文章

Teamcity 构建链问题

弹簧配置文件和测试

无法确定合适的驱动程序类弹簧

Visual Studio 预处理器仅在设置 /P 时才有效

使用 bootWar 设置活动弹簧配置文件

如何使用 Maven 配置文件设置弹簧活动配置文件