Gradle 执行测试的速度非常慢,因为它向套件添加了很多测试

Łuk*_*ąży 5 java testng intellij-idea gradle spring-boot

我有大约 8 个端到端测试类,它们扩展了我的抽象SpringContextLoadingTest 类,如下所示:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public abstract class SpringContextLoadingTest extends AbstractTestNGSpringContextTests {
}
Run Code Online (Sandbox Code Playgroud)

我有带有@SpringBootApplication注释的主应用程序类。

当我使用 TestNG 时,我在一组(“通道 A”)中有一些类,在另一组(“通道 B”)有一些类。

我为运行单独的组创建了 gradle 任务:

task runChannelA(type: Test) {
    forkEvery = 1
    useTestNG() {
        includeGroups "channel A"
    }
}
Run Code Online (Sandbox Code Playgroud)

如果没有“forEvery = 1”,则在运行超过 1 个测试时会出现端口繁忙的问题。

由于下面这个简单的配置,我从 gradle 任务执行中收到了更详细的输出:

tasks.withType(Test) {
    testLogging.showStandardStreams = true
}
Run Code Online (Sandbox Code Playgroud)

如果没有它,测试执行后,应用程序会在关闭 EntityManagerFactory 时挂起 2 分钟,但此标志显示 gradle 拾取了它没有被要求的测试。对于每个测试,无论它属于哪个组,gradle 都会记录:

Gradle Test Executor 22 STANDARD_OUT
2016-12-21 17:10:00.115  INFO   --- [    Test worker] .b.t.c.SpringBootTestContextBootstrapper : Neither @ContextConfiguration nor @ContextHierarchy found for test class [mypackage.OtherTest], using SpringBootContextLoader
2016-12-21 17:10:00.141  INFO   --- [    Test worker] o.s.t.c.support.AbstractContextLoader    : Could not detect default resource locations for test class [mypackage.OtherTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2016-12-21 17:10:00.143  INFO   --- [    Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [mypackage.OtherTest]: DbCongestionExploratoryTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2016-12-21 17:10:00.455  INFO   --- [    Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration mypackage.Application for test class mypackage.OtherTest
2016-12-21 17:10:00.466  INFO   --- [    Test worker] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@9404cc4, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@46876feb, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@dd46df5, org.springframework.test.context.support.DirtiesContextTestExecutionListener@49e2c374]
Run Code Online (Sandbox Code Playgroud)

这需要很多时间,因为我还有很多其他测试。当我在 IntelliJ 中看到我想要执行的测试已经通过之后,就会发生这种情况。例如,我在 25 秒后看到测试已通过,但因为它正在与我的项目中以这种方式设置的所有其他测试一起做任何事情,所以 runChannelA 需要超过 3 分钟。有趣的是,我可以在这种奇怪的行为期间停止该过程,IntelliJ 中的进度条会填满到最后,就像什么都没有发生一样,一切都是绿色的,很棒。

有人可以帮我弄这个吗?

Łuk*_*ąży 5

由于回答了这个问题,我已经解决了我的问题 - 在 junit 测试类中重用 spring 应用程序上下文

因为 Spring 不知道 JUnit 何时完成,所以它会永久缓存所有上下文并使用 JVM 关闭挂钩关闭它们。

这就是为什么对于不同的上下文,您需要不同的 jvm,因为只有在关闭 jvm 时才会删除上下文。

不幸的是,如果你在 gradle 任务中使用“forkEvery =1”,那么 Spring 会为类路径中的每个上下文分叉 jvm,包括当前正在执行的任何测试中未使用的上下文。

我有许多不同的上下文,因为我试图为每个测试仅加载所需的最低配置。

我已经解决了尽可能按上下文对测试进行分组的问题。我扩展了 SpringContextLoadingTest 以加载更多内容。它现在涵盖了我的大部分测试。使用此上下文的测试在一个 gradle 任务中运行,没有forkEvery = 1。我需要加载不同上下文的测试(因为我更改了某些属性或加载了 bean 的不同版本)我在另一个 gradle 任务中运行,这次是指定 forkEvery = 1。