Maven命令首次运行测试时Junit TestExecutionListener未触发
问题:JUnit 5 TestExecutionListener首次Maven运行不触发,后续及IDEA运行正常
现象
- 基于JUnit 5 + Rest Assured做API测试,自定义了
RunnerExtension实现TestExecutionListener,用来打印测试执行的开始/结束日志 - 第一次执行
mvn test -Duri=http://localhost:8000/api时,监听器完全没反应 - 用IntelliJ IDEA直接运行测试类,监听器正常工作;首次Maven运行失败后,再执行相同命令,监听器又能正常触发
- CI/CD流水线要求首次Maven运行必须生效,当前情况无法满足需求
环境信息
- Java:openjdk version "1.8.0_292" (AdoptOpenJDK)
- Maven:Apache Maven 3.9.6
相关配置与代码
1. SPI注册文件
路径:src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener
utils.listeners.RunnerExtension
2. 自定义监听器代码
public class RunnerExtension implements TestExecutionListener { @Override public void testPlanExecutionStarted(TestPlan testPlan) { System.out.println("========STARTING============"); } @Override public void testPlanExecutionFinished(TestPlan testPlan) { System.out.println("========FINISHING============="); } }
3. Maven POM核心配置
<properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <restassured.version>4.0.0</restassured.version> <junit.version>5.7.2</junit.version> <maven-surefire-plugin.version>3.0.0-M4</maven-surefire-plugin.version> <aspectj.version>1.9.6</aspectj.version> <!-- 其他依赖版本省略 --> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>${maven-surefire-plugin.version}</version> <configuration> <properties> <configurationParameters> junit.jupiter.conditions.deactivate = * junit.jupiter.extensions.autodetection.enabled = true junit.jupiter.testinstance.lifecycle.default = per_class </configurationParameters> </properties> <systemPropertyVariables> <allure.results.directory>target/allure-results</allure.results.directory> </systemPropertyVariables> <argLine> -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" </argLine> </configuration> </plugin> <!-- 其他插件省略 --> </plugins> </build>
已排查内容
- 确认JAVA_HOME指向Java 8环境,编译、运行版本一致
- 对比首次与后续Maven运行的debug日志(
mvn test -X),未发现依赖库差异
解决方案
1. 确保SPI注册文件被正确复制到测试类路径
首次运行时,META-INF/services下的注册文件可能未被正确复制。添加maven-resources-plugin配置强制复制:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.1</version> <executions> <execution> <id>copy-test-resources</id> <phase>process-test-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.testOutputDirectory}</outputDirectory> <resources> <resource> <directory>src/test/resources</directory> <includes> <include>META-INF/services/**</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin>
2. 升级Maven Surefire插件到稳定版
当前使用的3.0.0-M4是预览版本,存在类路径加载的已知问题。升级到3.2.5这类稳定版本,同时Java 8环境下需关闭模块路径模式:
<!-- 更新版本属性 --> <maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version> <!-- 插件配置添加useModulePath=false --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>${maven-surefire-plugin.version}</version> <configuration> <useModulePath>false</useModulePath> <!-- 保留原有其他配置 --> </configuration> </plugin>
3. 直接在Surefire配置中显式注册监听器
跳过SPI自动注册,直接在插件里指定监听器:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>${maven-surefire-plugin.version}</version> <configuration> <properties> <configurationParameters> junit.platform.launcher.listeners = utils.listeners.RunnerExtension <!-- 保留原有其他配置 --> </configurationParameters> </properties> <!-- 保留原有其他配置 --> </configuration> </plugin>
4. 清理Maven缓存后重新测试
首次运行可能存在缓存导致的类加载异常,先清理再执行测试:
mvn clean test -Duri=http://localhost:8000/api
内容的提问来源于stack exchange,提问作者Vladyslav Tolosiuk
相关产品推荐
相关产品推荐

