如何 run/turn 关闭基于 spring 启动配置文件的选择性测试

how to run/turn off selective tests based on profiles in spring boot

我有一个 spring-boot 应用程序,我正在为其编写 IT 测试。

当我激活 dev 配置文件

时,测试数据来自 application-dev.properties

这是我要测试的内容:

@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
public class ApplicationTests {

    @Autowired
    Environment env;

    @Test
    public void contextLoads() {
        System.out.println(Arrays.toString((env.getActiveProfiles())));

    }

}

ServiceITTest

public class ServiceITTest extends ApplicationTests {


     @value
     String username;

     @value
     String address;

     @Autowired
     MyService myService;


      @Test
      public void check_for_valid_username_address(){
            myService.validate(username,address);
      }
}

我只希望在设置 "dev"、"qa" 的配置文件时将上述测试设为 运行。默认情况下,它不应该 运行.

是否有可能在 spring 引导测试中获得精细控制?

您可能希望使用 @IfProfileValue 注释。不幸的是,它不能直接在活动配置文件上工作,但它可以读取 属性,因此如果您只在要 运行 测试的配置文件中定义特定的 属性,那么您可以在特定 属性.

上使用该注释

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#integration-testing-annotations-junit

我想排除需要外部服务的测试,但我无法让它按照我想要的方式工作(或多或少是不存在的 @IfNotProfileValue)。

作为替代方案,我使用了 JUnit Assume.assumeThat,它提供了我想要的行为。例如,

Assume.assumeThat("Skipping Test: No username property", this.username, not(isEmptyString()));

我最终没有使用配置文件来驱动它,但您应该能够定义一个 属性 或使用环境来确定配置文件是否处于活动状态。

assumeThat 可用于 @Test@Before 方法,但请注意 @After 方法仍将 运行,因此清理可能需要代码守卫。

它也适用于活动配置文件 - 有一个包含活动配置文件的 属性 值:

仅针对特定配置文件进行测试:

@IfProfileValue(name = "spring.profiles.active", values = {"specific"})

因为我的测试不应该 运行 如果特定配置文件处于活动状态,我将其添加到这些测试中:

@ActiveProfiles(profiles = {"default"})

它不适用于 @IfProfileValue 和 "default",而且我也没有发现任何“运行 如果特定配置文件未激活。

在 Spring 中您还可以使用 @DisabledIf 注释。它允许为示例指定 Spring Expression Language expression. See this blog post

JUnit 5 还有:

  • @DisabledIfEnvironmentVariable
  • @DisabledIfSystemProperty

您可以使用 org.springframework.core.env.Environment 获取活动配置文件: (注意,这是 Kotlin。)

@Autowired
private val environment: Environment? = null

private fun isProfileActive(name: String) = environment!!.activeProfiles.contains(name)

@Test fun onlyOnOpenShift {
     org.junit.Assume.assumeTrue(isProfileActive("openshift"));
     ...
}

如果你在很多情况下都会使用它(我建议这可能暗示你做错了什么),那么用 [=14 这样的注释装饰测试方法可能会有所回报=] 并使用您自己的 JUnit 扩展处理它,例如,实现 org.junit.jupiter.api.extension.BeforeTestExecutionCallback 并确定该方法是否应该 运行。在这种情况下,可以从 Spring 测试 运行ner.

中获取环境。
@Test @OnlyIfProfileActive("openshift")
fun onlyOnOpenShift {
     ...
}

我怀疑是像 @IfProfileValue 这样的注释所做的。但在这里你会有更多的控制权。

例如,为了使其通用,它可以是用 JEXL 或 JUEL 等计算的表达式。

@Test @SpringProfilesCondition("openshift && !mockDatabase")
fun onlyOnOpenShift {
     ...
}

我最近不得不这样做。

import org.springframework.core.env.Environment;
import static org.junit.Assume.assumeFalse;

@Test
public void testSomethingWhenProfileIsNot(){
  assumeFalse("Ignore this test when the active profile is 'myprofile'",
     Arrays.stream(environment.getActiveProfiles()).anyMatch( profileName -> "myprofile".equals(profileName)));

}


@Test
@IfProfileValue(name = "spring.profiles.active", value = "myprofile")
public void testSomethingWhenProfileIs(){
  
}

我不得不做类似的事情,使用 Spring 属性 YAML 文件禁用/启用 @Test 方法,因为不同的环境具有不同的功能,这些功能被关闭/打开。

解决方案是创建自定义注释,例如FeatureAFeatureB 例如

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@DisabledIf(value = "${ignore-feature.billing}", loadContext = true)
public @interface FeatureBilling {

}

...和...

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@DisabledIf(value = "${ignore-feature.webhooks}", loadContext = true)
public @interface FeatureWebhooks {

}

测试方法可以注释为:-

@SpringBootTest
public class TestScenarios {

    @Test                         
    public void test1() {
        // always run      
    }

    @Test
    @FeatureBilling         // method tests billing functionality
    public void test2() {

    }

    @Test
    @FeatureWebhooks        // method tests webhooks 
    public void test3() {

    }

    @Test
    @FeatureWebhooks        // method also tests webhooks
    public void test4() {

    }

    ...

}

所以 application.yaml 文件可以包含例如

ignore-feature:
  billing: false
  webhooks: false
  ... 
  

这意味着特定环境可以非常细化我们测试或不测试哪些功能,例如

application-staging.yaml 可以覆盖这些并在适用的情况下禁用:-

ignore-feature:
  billing: true