Maven/Surefire 无法在同一个项目中执行 Spock 和 JUnit

sun*_*nzy 1 java junit maven spock maven-surefire-plugin

环境

  • 爪哇
$ 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)
Run Code Online (Sandbox Code Playgroud)
  • 行家
$ 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"
Run Code Online (Sandbox Code Playgroud)

问题

我分叉了spockframework/spock-example添加 java 测试目录和 HelloJUnitTest.java => sunzy/spock-exmaple

Spock 测试可以执行,但 JUnit 测试不能

快照

  • mvn 清洁测试

只有 spock 测试!

在此处输入图片说明

  • mvn clean test -Dtest=HelloJUnitTest

在此处输入图片说明

  • JUnit 测试已在目标/测试类中生成*

在此处输入图片说明

  • mvn clean test -Dtest=HelloSpocSpec

在此处输入图片说明

  • mvn -X 包含测试类

kri*_*aex 8

好的,我已经看了你的项目。正如您所说,这只是 Spock 示例项目,升级后可以运行 Spock 2 测试。顺便说一句,它仍然应该进一步升级,因为在当前的配置中,编译不适用于当前的 Java 版本,但这是题外话,我只是提到它,因为我遇到了问题,然后为了快速降级到 Java 8重现您的实际问题。JUnit 测试的包名也不是问题,即使默认包总是丑陋的,就像 Spock 测试一样。

Spock 1.x 基于 JUnit 4,但 Spock 2.x 基于 JUnit 5 平台。这也是神火在分析项目依赖时自动发现的。如果你想神火并行运行多个引擎,则需要配置相应的提供商插件的依赖关系,提到这里

在您的情况下,只需将其添加到 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>
Run Code Online (Sandbox Code Playgroud)

将 JUnit 4.12 或 4.13 的测试范围依赖项显式添加到 POM 也是有意义的,因为 JUnit 4.12 只是当前 POM 中的传递依赖项。但是后来的 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
Run Code Online (Sandbox Code Playgroud)

如果您决定从 JUnit 4 升级到 5,那么配置对您来说可能会变得更容易,因为 Spock 和 JUnit 使用相同的提供程序。在这种情况下,请添加 JUnit 5 依赖项,以便您的测试可以导入相应的测试注释和断言方法。


更新:在@khmarbaise 评论使用老式引擎并且我完全同意它是更好的解决方案之后,我想向您展示如何做到这一点,而不是向 Surefire 添加插件依赖项。(所以如果你想使用这个解决方案,你可以删除那些):

<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>
Run Code Online (Sandbox Code Playgroud)

为什么是 5.5.2 版而不是 5.6.2 版?为了避免版本冲突和后续关于老式引擎在 Groovy 目录中找不到测试的警告。这只是因为这个示例项目中的 POM 仍然使用 Spock 2.0-M1 BOM。正如我所说,它应该更新。但是在这个版本中它可以正常工作,因为它依赖于与此配置中的 Spock 相同的 JUnit 5 平台版本。

顺便说一句,现在 Maven 首先执行 Spock 测试,然后执行 JUnit 4 测试,因此两者的日志输出顺序相反。