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
相关产品推荐
相关产品推荐

