【问题标题】:How to run all test classes but only start embedded Tomcat once when using Spring Boot?使用 Spring Boot 时如何运行所有测试类但只启动嵌入式 Tomcat 一次?
【发布时间】:2018-08-15 07:20:53
【问题描述】:

我的项目有很多 Test 这样的类:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class RefererCheckerTest {
...

每次我想运行所有测试类时,每个人都会显示这样的日志:

2018-08-15 14:59:31.104 [主要] 信息 o.s.b.c.e.t.TomcatEmbeddedServletContainer [TomcatEmbeddedServletContainer.java:201] -Tomcat 在端口上启动: 63003 (http)

2018-08-15 14:59:31.112 [主要] 信息 c.b.s.m.filter.OAuthLoginTest [StartupInfoLogger.java:57] - 已启动 OAuthLoginTest 27.571 秒(JVM 运行 33.229)

似乎初始化一个 Spring Boot 项目及其嵌入式 Tomcat 需要花费很多时间。如果我有 100 个测试类,运行所有测试类将花费我 27.571 seconds *100

在运行所有 100 个测试类时,我是否可以只初始化一次 Spring Boot 和 Embedded Tomcat?这样可以节省时间。

【问题讨论】:

  • 不应该那样做。如果您使用相同的注释,则上下文和tomcat 将启动一次。如果他们这样做了,那么这些测试类中肯定有一些不同的东西(比如使用@MockBean@SpyBean 或不同的属性等)。

标签: java spring spring-boot tomcat


【解决方案1】:

有很多场景可能会导致 spring-context 重新加载并启动新服务器,例如:

  • @DirtContext:
  • @TestPropertySource
  • 不同的@ContextConfgiurations
  • @WebMvcTest / @SpringBootTest / @SpringBootConfiguration 的组合
  • 不同的@ActiveProfiles

所以,让我说一下我们通常在这里使用什么来避免这个问题:

首先,我们创建一个包含测试的所有参数和配置的抽象类:

@RunWith(SpringRunner.class)
@ActiveProfiles("test") 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = [<your application class OR context class>])
public abstract class AbstractSpringBootTest {
}

然后,在所有测试中,我扩展了这个测试类:

public class RefererCheckerTest extends AbstractSpringBootTest {
   ....
}

如果所有测试都包含相同的配置,这会使 SpringBoot 在测试期间仅启动一次。

我们目前使用 Spring-Boot 2.0.4.RELEASE,它运行良好。

注意:我们也使用 SpringRunner 而不是 SpringJUnit4ClassRunner,它从 spring-test:4.3+ 开始可用,并且需要 JUnit 4.12+。

此外,即使 spring-boot 重新启动,它也应该只重新加载部分上下文,而不是重新加载所有内容并花费相同的时间。另外,请检查您是如何运行测试的。

【讨论】:

    猜你喜欢
    • 2014-12-12
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 2017-01-22
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多