Maven/Surefire 无法在同一项目中执行 Spock 和 JUnit
Maven/Surefire can't execute Spock and JUnit in the same project
环境
- java
$ java -version
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
- 行家
$ mvn -version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.3\plugins\maven\lib\maven3
Java version: 1.8.0_231, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk1.8.0_231\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
- pom.xml -- Forked from spockframework/spock-example
问题
我分叉了spockframework/spock-example add java test directory and HelloJUnitTest.java => sunzy/spock-exmaple
Spock 测试可以执行,但 JUnit 测试不能
快照
- mvn clean test
只有 spock 测试!
- mvn clean test -Dtest=HelloJUnitTest
- JUnit 测试已在 target/test-classes*
中生成
- mvn clean test -Dtest=HelloSpocSpec
- mvn -X 包含测试类
好的,我已经看过你的项目了。如您所说,它只是 Spock 示例项目,已升级为 运行 Spock 2 测试。 顺便说一句,它仍然应该进一步升级,因为在当前配置中编译不适用于当前 Java 版本,但这不是主题,我只是提到它因为我 运行 进入问题然后降级为 Java 8 以便快速重现您的实际问题。 JUnit 测试的包名称也不是问题,即使默认包总是丑陋的,就像 for Spock 测试。
Spock 1.x 基于 JUnit 4,但 Spock 2.x 基于 JUnit 5 平台。这也是Surefire在分析项目依赖时自动找到的。如果想让Surefire运行多个引擎并行,需要将相应的provider配置为插件依赖,如here.
所述
对于您的情况,只需将其添加到 POM 中:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<useFile>false</useFile>
<includes>
<include>**/*Test.java</include>
<include>**/*Spec.java</include>
</includes>
</configuration>
<!-- Run Spock 2 and JUnit 4 tests in parallel -->
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>3.0.0-M4</version>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit-platform</artifactId>
<version>3.0.0-M4</version>
</dependency>
</dependencies>
</plugin>
将 JUnit 4.12 或 4.13 的测试范围依赖项显式添加到您的 POM 也是有意义的,因为 JUnit 4.12 在您当前的 POM 中只是一个 t运行sitive 依赖项。但后来的 Spock 2 版本可能会删除该依赖项,因为它并不是真正需要的。我认为 2.0-M3 已经发生了。所以要小心。
此更改后,Maven 说:
[INFO] --- maven-surefire-plugin:3.0.0-M4:test (default-test) @ spock-example ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running HelloJUnitTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.059 s - in HelloJUnitTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running DatabaseDrivenSpec
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.171 s - in DatabaseDrivenSpec
(...)
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 39, Failures: 0, Errors: 0, Skipped: 0
如果您决定从 JUnit 4 升级到 5,配置对您来说可能会更容易,因为 Spock 和 JUnit 使用相同的提供程序。在这种情况下,请添加 JUnit 5 依赖项,以便您的测试可以导入相应的测试注释和断言方法。
更新: 在@khmarbaise 评论使用老式引擎并且我完全同意这是更好的解决方案之后,我想向您展示如何做到这一点而不是添加插件依赖项到万无一失。 (所以如果你想使用这个解决方案,你可以删除那些):
<dependency> <!-- only required if you want to run JUnit 4 tests alongside Spock 2 -->
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
为什么是 5.5.2 版本而不是例如5.6.2?为了避免版本冲突和随后关于 vintage engine not finding tests in the Groovy directory 的警告。这是因为此示例项目中的 POM 仍然使用 Spock 2.0-M1 BOM。正如我所说,它应该更新。但是对于这个版本,它可以正常工作,因为它依赖于与此配置中的 Spock 相同的 JUnit 5 平台版本。
顺便说一句,现在 Maven 先执行 Spock 测试,然后执行 JUnit 4 测试,因此两者的日志输出顺序会相反。
环境
- java
$ java -version
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
- 行家
$ mvn -version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.3\plugins\maven\lib\maven3
Java version: 1.8.0_231, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk1.8.0_231\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
- pom.xml -- Forked from spockframework/spock-example
问题
我分叉了spockframework/spock-example add java test directory and HelloJUnitTest.java => sunzy/spock-exmaple
Spock 测试可以执行,但 JUnit 测试不能
快照
- mvn clean test
只有 spock 测试!
- mvn clean test -Dtest=HelloJUnitTest
- JUnit 测试已在 target/test-classes* 中生成
- mvn clean test -Dtest=HelloSpocSpec
- mvn -X 包含测试类
好的,我已经看过你的项目了。如您所说,它只是 Spock 示例项目,已升级为 运行 Spock 2 测试。 顺便说一句,它仍然应该进一步升级,因为在当前配置中编译不适用于当前 Java 版本,但这不是主题,我只是提到它因为我 运行 进入问题然后降级为 Java 8 以便快速重现您的实际问题。 JUnit 测试的包名称也不是问题,即使默认包总是丑陋的,就像 for Spock 测试。
Spock 1.x 基于 JUnit 4,但 Spock 2.x 基于 JUnit 5 平台。这也是Surefire在分析项目依赖时自动找到的。如果想让Surefire运行多个引擎并行,需要将相应的provider配置为插件依赖,如here.
所述对于您的情况,只需将其添加到 POM 中:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<useFile>false</useFile>
<includes>
<include>**/*Test.java</include>
<include>**/*Spec.java</include>
</includes>
</configuration>
<!-- Run Spock 2 and JUnit 4 tests in parallel -->
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>3.0.0-M4</version>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit-platform</artifactId>
<version>3.0.0-M4</version>
</dependency>
</dependencies>
</plugin>
将 JUnit 4.12 或 4.13 的测试范围依赖项显式添加到您的 POM 也是有意义的,因为 JUnit 4.12 在您当前的 POM 中只是一个 t运行sitive 依赖项。但后来的 Spock 2 版本可能会删除该依赖项,因为它并不是真正需要的。我认为 2.0-M3 已经发生了。所以要小心。
此更改后,Maven 说:
[INFO] --- maven-surefire-plugin:3.0.0-M4:test (default-test) @ spock-example ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running HelloJUnitTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.059 s - in HelloJUnitTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running DatabaseDrivenSpec
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.171 s - in DatabaseDrivenSpec
(...)
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 39, Failures: 0, Errors: 0, Skipped: 0
如果您决定从 JUnit 4 升级到 5,配置对您来说可能会更容易,因为 Spock 和 JUnit 使用相同的提供程序。在这种情况下,请添加 JUnit 5 依赖项,以便您的测试可以导入相应的测试注释和断言方法。
更新: 在@khmarbaise 评论使用老式引擎并且我完全同意这是更好的解决方案之后,我想向您展示如何做到这一点而不是添加插件依赖项到万无一失。 (所以如果你想使用这个解决方案,你可以删除那些):
<dependency> <!-- only required if you want to run JUnit 4 tests alongside Spock 2 -->
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
为什么是 5.5.2 版本而不是例如5.6.2?为了避免版本冲突和随后关于 vintage engine not finding tests in the Groovy directory 的警告。这是因为此示例项目中的 POM 仍然使用 Spock 2.0-M1 BOM。正如我所说,它应该更新。但是对于这个版本,它可以正常工作,因为它依赖于与此配置中的 Spock 相同的 JUnit 5 平台版本。
顺便说一句,现在 Maven 先执行 Spock 测试,然后执行 JUnit 4 测试,因此两者的日志输出顺序会相反。