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

Maven Surefire插件为何执行两次?如何消除空测试执行?

问题:Maven执行测试时出现两次测试结果输出,第一次显示0个测试执行

我有一个使用Maven构建、Spock框架编写单元测试的Java多模块应用,正在将Groovy版本从2.5.7升级到3.0.19,Spock版本从1.3-groovy-2.5升级到2.3-groovy-3.0。

相关配置

属性配置

<mavenSurefirePluginVersion>3.0.0-M4</mavenSurefirePluginVersion>
<gmaven-plugin.version>1.5</gmaven-plugin.version>
<gmaven-runtime.version>1.5</gmaven-runtime.version>
<java.version>11</java.version>
<mavenCompilerPluginVersion>3.8.0</mavenCompilerPluginVersion>

父模块插件配置

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>${java.version}</source>
            <target>${java.version}</target>
        </configuration>
    </plugin>

    <plugin>
        <groupId>org.codehaus.gmaven</groupId>
        <artifactId>gmaven-plugin</artifactId>
        <version>${gmaven-plugin.version}</version>
        <configuration>
            <providerSelection>2.0</providerSelection>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>compile</goal>
                    <goal>testCompile</goal>
                </goals>
            </execution>
        </executions>
        <dependencies>
            <dependency>
                <groupId>org.codehaus.gmaven.runtime</groupId>
                <artifactId>gmaven-runtime-2.0</artifactId>
                <version>${gmaven-runtime.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-all</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.codehaus.groovy</groupId>
                <artifactId>groovy-all</artifactId>
                <version>${groovyVersion}</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    </plugin>
    <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${mavenSurefirePluginVersion}</version>
        <configuration>
            <properties>
                <property>
                    <name>listener</name>
                    <value>org.sonar.java.jacoco.JUnitListener</value>
                </property>
            </properties>
            <testFailureIgnore>false</testFailureIgnore>
            <useFile>false</useFile>
            <includes>
                <include>**/*Spec.java</include>
            </includes>
        </configuration>
        <dependencies>
            <dependency>
                <groupId>org.apache.maven.surefire</groupId>
                <artifactId>surefire-junit47</artifactId>
                <version>${mavenSurefirePluginVersion}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.maven.surefire</groupId>
                <artifactId>surefire-junit-platform</artifactId>
                <version>${mavenSurefirePluginVersion}</version>
            </dependency>
        </dependencies>
    </plugin>
</plugins>

已添加的测试依赖

<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-engine</artifactId>
    <version>1.9.0</version>
    <scope>test</scope>
</dependency>

子模块test-base的插件配置

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${mavenCompilerPluginVersion}</version>
            <configuration>
                <source>11</source>
                <target>11</target>
                <generatedSourcesDirectory>${project.build.directory}/generated-sources/</generatedSourcesDirectory>
                <compilerArgument>-proc:none</compilerArgument>
            </configuration>
        </plugin>
    </plugins>
</build>

执行mvn clean compile install后的日志片段

[INFO] --- gmaven-plugin:1.5:testCompile (default) @ test-base ---
[INFO] Compiled 17 Groovy classes
[INFO] 
[INFO] --- maven-surefire-plugin:3.0.0-M4:test (default-test) @ test-base ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------

--- running tests----
[INFO] Results:
[INFO] 
[INFO] Tests run: 28, Failures: 0, Errors: 0, Skipped: 0

原因分析

出现两次测试结果输出的核心原因是Surefire插件同时引入了JUnit 4和JUnit Platform两个测试引擎依赖:

  • 第一个测试执行结果(0个测试)来自surefire-junit47引擎:Spock 2.x基于JUnit 5/JUnit Platform运行,JUnit 4引擎无法识别Spock 2.x的测试类(*Spec.groovy),且配置中仅指定包含**/*Spec.java,因此找不到测试用例,输出0测试。
  • 第二个测试执行结果(28个测试)来自surefire-junit-platform引擎:该引擎能正确识别Spock 2.x的测试,执行所有测试并输出正确结果。

另外,GMaven插件版本1.5较老旧,对Groovy 3.x的支持有限,也可能间接导致测试编译或识别的异常,但核心冲突点是Surefire的多引擎配置。

解决方案

1. 移除Surefire插件中的JUnit 4引擎依赖

删除surefire-junit47的依赖配置,只保留surefire-junit-platform,确保只有JUnit Platform引擎负责执行测试,同时调整测试类匹配规则包含Groovy文件:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${mavenSurefirePluginVersion}</version>
    <configuration>
        <properties>
            <property>
                <name>listener</name>
                <value>org.sonar.java.jacoco.JUnitListener</value>
            </property>
        </properties>
        <testFailureIgnore>false</testFailureIgnore>
        <useFile>false</useFile>
        <includes>
            <include>**/*Spec.java</include>
            <include>**/*Spec.groovy</include>
        </includes>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-junit-platform</artifactId>
            <version>${mavenSurefirePluginVersion}</version>
        </dependency>
    </dependencies>
</plugin>

2. 替换GMaven插件为Groovy Maven插件

GMaven插件已停止维护,对Groovy 3.x支持不佳,建议替换为官方的groovy-maven-plugin:

<!-- 移除旧的GMaven插件配置 -->
<plugin>
    <groupId>org.codehaus.gmaven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>${gmaven-plugin.version}</version>
</plugin>
<!-- 添加Groovy Maven插件 -->
<plugin>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy-maven-plugin</artifactId>
    <version>3.0.17</version> <!-- 匹配Groovy 3.x版本 -->
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>testCompile</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <source>${java.version}</source>
        <target>${java.version}</target>
    </configuration>
</plugin>

3. 确保Spock 2.x依赖完整

确认Spock 2.x的依赖配置正确,包含核心包和JUnit 5适配包:

<dependency>
    <groupId>org.spockframework</groupId>
    <artifactId>spock-core</artifactId>
    <version>2.3-groovy-3.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.spockframework</groupId>
    <artifactId>spock-junit5</artifactId>
    <version>2.3-groovy-3.0</version>
    <scope>test</scope>
</dependency>

4. 更新Surefire插件版本(可选)

3.0.0-M4是较旧的里程碑版本,建议升级到稳定版(如3.2.5),提升兼容性和稳定性:

<mavenSurefirePluginVersion>3.2.5</mavenSurefirePluginVersion>

验证

修改配置后,重新执行mvn clean test,日志应仅输出一次测试结果,显示28个测试执行完成。

内容的提问来源于stack exchange,提问作者Remo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:24:57