在 Spring Boot 中跳过关于 *** DNS 可用性的集成测试
Posted
技术标签:
【中文标题】在 Spring Boot 中跳过关于 *** DNS 可用性的集成测试【英文标题】:Skipping integration tests in spring boot on *** DNS availability 【发布时间】:2019-11-07 10:31:25 【问题描述】:我有一个中等繁重的 springboot 服务,启动快乐流需要 10-15 秒,重试/故障转移流需要 (1-2) 分钟失败。这对我的业务流程来说没问题,也是我期望健康服务的行为方式。
我有集成测试(在我的服务中运行一些端到端流程),只能在测试机器(或开发机器)连接到特定 *** 时测试实际集成状态。
如果我没有连接到 ***,我想自动跳过集成测试。
考虑下面的代码
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Server.class, // auto scans a bunch of components
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) // slow loading context
public class IntegrationTest
@BeforeClass
public static void beforeClass()
Assume.assumeTrue(DnsTool.***Connected()); // fast failing test
@Test
public void testIntegration()
// some test logic
当假设通过时,我的测试就会运行,一切都很好。 当假设失败时,我的测试会被跳过,但只有在尝试加载昂贵的上下文之后。
如何避免我的测试套件运行时间过长?
我尝试过的事情:
继承SpringJUnit4ClassRunner
,并覆盖isTestMethodIgnored
。
添加TestExecutionListener
,并在beforeTestClass
中抛出假设异常
这些对 Spring 没有任何影响,并且上下文以任何方式加载。
我没有尝试过的事情:
我认为 Lazy init 附带了 2.2.X 的下一个 Spring 稳定版本。懒惰的初始化可能会让我的问题消失,但我觉得应该有一些我缺少的简单的 spring-test/junit 修复。
提前感谢您的帮助。
【问题讨论】:
【参考方案1】:对我来说,这听起来像是你根本不应该在测试中做的事情。 测试(至少恕我直言)应该检查业务案例并假设环境已设置并准备就绪。
也许值得将此功能委托给构建工具和 CI。
例子:
在 maven(或您使用的任何构建工具)中定义一个配置文件,该配置文件将运行需要 *** 的集成测试。定义将运行所有其余集成测试的配置文件。 如果某些系统属性可用,请激活配置文件。
在作为 CI 的一部分的 CI 工具(如 Jenkins)中,甚至在您运行 maven 之前,运行将检查 *** 连接的脚本。根据结果设置系统属性并使用这些属性运行 maven。将加载所需的配置文件并运行所有测试/仅不需要 *** 的测试。
更新
如果你需要让它从 Spring 开始工作(看起来你更喜欢这种方式),
Spring有一个特殊的注解叫做@IfProfileValue
默认情况下,它与系统属性匹配,如果值不匹配,则忽略测试。
看起来像这样(请注意,您也可以将此注释放在类上,然后它将适用于类中的所有测试方法):
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTestClass
@IfProfileValue(name = "os.name", values = "Linux")
@Test
public void testMe()
// will run only in linux, otherwise
// won't even try to load an
// application context
....
这涵盖了您从外部解析 *** 连接并使用属性运行测试的情况。但是,如果你想在 java 中实现 *** 连接检查,这个注解是不够的,因为它只能与 Java 系统属性一起使用,所以为了使用自定义逻辑,你需要实现 org.springframework.test.annotation.ProfileValueSource
:
public class ***ConnectivityProfileValueSource implements ProfileValueSource
private String ***Enabled = "true";
public ***ConnectivityProfileValueSource ()
// no spring context is available here
ClassPathResource resource = new ClassPathResource("***-config.properties");
if (resource.exists())
// read the *** address,
//
//this.testProps = PropertiesLoaderUtils.loadProperties(resource);
// invoke your utility, check the connectivity, etc.
this.***Enabled = ...
@Override
public String get(String key)
// this is important method,
if(key.equals("***.enabled")
return this.***Enabled;
else return System.getProperty(key);
最后一件事是让测试知道 ProfileValueSource:
为此,您在测试中添加了另一个特殊注释:
@ProfileValueSourceConfiguration(***ConnectivityProfileValueSource.class)
总而言之,测试看起来像这样:
@RunWith(SpringRunner.class)
@SpringBootTest
@ProfileValueSourceConfiguration(***ConnectivityProfileValueSource.class)
@IfProfileValue(name = "***.enabled", value = "true")
public class MyTestClass
@Test
public void testMe()
....
我提到的所有类/注释都位于包org.springframework.test.annotation
【讨论】:
你基本上是说我在junit中使用了假设,比他们打算使用的要难一些。我的意思是“纯文本”我的集成测试,假设一个有效的 *** 连接。在我知道 junit 中的假设存在之前,我会完全转向 CI 解决方案。我是一个被宠坏的开发人员,我想要一个解决方案JAVA 当测试运行时(即使它没有加载应用程序竞赛)它会提供某种报告来确保以后影响构建结果......那么如果没有启用 *** 怎么办,测试地位真的体现吗?只是我的想法...... 来自 juint4 的假设文档:失败的假设通常不会被记录,因为可能有许多测试不适用。在詹金斯上,我只是从我的可靠结果中获得了“跳过”测试的日志……这没关系 IMO 也许你可以在Server.class上设置一个条件注释呢?这样应用上下文会加载得更快,因为它实际上不会扫描任何东西? 嘿,我已经用 Java/Spring 解决方案更新了答案。请查看以上是关于在 Spring Boot 中跳过关于 *** DNS 可用性的集成测试的主要内容,如果未能解决你的问题,请参考以下文章
spring cloud gateway 某些路由中跳过全局过滤器