测试类使用CompletableFuture时Jenkins构建失败问题求助
问题根因分析
- 并发测试下资源冲突导致VM异常退出:你配置了
forkCount=4且reuseForks=false,4个测试类各自启动独立的JVM进程运行,每个进程都会初始化完整的SpringBoot上下文(包含Quartz调度池、业务异步线程池等组件)。Jenkins构建节点资源通常受限,多进程同时启动大量线程极易触发系统资源阈值,导致部分fork进程被系统强制杀死,就会抛出SurefireBooterForkException: The forked VM terminated without properly saying goodbye报错。即使测试用例本身执行全过(如片段1显示10个用例0失败),只要有fork进程异常退出,surefire插件就会判定测试失败。 - 异步任务未完成触发上下文销毁异常:你的业务逻辑大量使用
CompletableFuture异步执行,若存在未被join()/get()等待的游离异步任务,测试用例跑完后Spring上下文会提前启动销毁流程,强制关闭线程池,此时运行中的异步任务会抛出未捕获的Execution异常,对应片段3中的测试执行错误。 - 插件版本兼容缺陷:你使用的
maven-surefire-plugin:2.22.2版本存在JDK11适配bug,fork模式下经常出现测试结果采集丢失、进程退出状态识别错误的问题。
解决方案
1. 修复异步任务与线程池配置(必做)
在所有@SpringBootTest的properties配置中添加线程池优雅关闭参数,确保异步任务全部执行完成后再销毁上下文:
@SpringBootTest(properties = { "spring.cloud.config.enabled: false", "logging.level.path.to.main.class: OFF", // 新增以下配置 "spring.task.execution.shutdown.await-termination=true", "spring.task.execution.shutdown.await-termination-period=30s", "spring.quartz.auto-startup=false" // 测试环境禁用Quartz,避免无关线程干扰 })
同时检查所有测试用例,确保业务逻辑中产生的所有CompletableFuture实例都被显式等待完成,不存在无归属的异步任务。
2. 调整maven-surefire-plugin配置
首先升级插件版本解决兼容问题,再根据需求调整并行策略:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.2</version> <!-- 升级到最新稳定版 --> <configuration> <!-- 先临时改成1验证问题是否消失,确认是并行问题后再调整:如果要保留并行,建议改为2,避免资源占用过高 --> <forkCount>1</forkCount> <reuseForks>true</reuseForks> <!-- 复用进程减少开销 --> <forkedProcessExitTimeoutInSeconds>60</forkedProcessExitTimeoutInSeconds> <!-- 给足进程退出上报时间 --> </configuration> </plugin>
3. 优化测试上下文复用(可选,提升测试性能)
抽取公共测试父类,统一配置SpringBoot测试参数,所有测试类继承该父类,避免每个测试类独立启动上下文,大幅降低资源消耗。
内容的提问来源于stack exchange,提问作者Wrapper
相关产品推荐
相关产品推荐

