You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:18:12