Maven/Surefire 无法在同一个项目中执行 Spock 和 JUnit [英] Maven/Surefire can't execute Spock and JUnit in the same project

查看:41
本文介绍了Maven/Surefire 无法在同一个项目中执行 Spock 和 JUnit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

环境

  • java

$ java -versionjava版本1.8.0_241"Java(TM) SE 运行时环境(构建 1.8.0_241-b07)Java HotSpot(TM) 64 位服务器 VM(构建 25.241-b07,混合模式)

  • 行家

$ mvn -versionApache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)Maven 主目录:C:Program FilesJetBrainsIntelliJ IDEA 2019.2.3pluginsmavenlibmaven3Java 版本:1.8.0_231,供应商:Oracle Corporation,运行时:C:Program FilesJavajdk1.8.0_231jre默认语言环境:zh_CN,平台编码:GBK操作系统名称:windows 10",版本:10.0",架构:amd64",系列:windows"

    • mvn clean test -Dtest=HelloJUnitTest

    • JUnit 测试在 target/test-classes*
    • 中生成

    • mvn clean test -Dtest=HelloSpocSpec

    • mvn -X 包含测试类

    解决方案

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

    Spock 1.x 基于 JUnit 4,但 Spock 2.x 基于 JUnit 5 平台.这也是神火在分析项目依赖时自动发现的.如果你想让 Surefire 并行运行多个引擎,你需要将相应的提供者配置为插件依赖项,如前所述 此处.

    在您的情况下,只需将其添加到 POM:

     <artifactId>maven-surefire-plugin</artifactId><version>3.0.0-M4</version><配置><useFile>false</useFile><包括><include>**/*Test.java</include><include>**/*Spec.java</include></包括></配置><!-- 并行运行 Spock 2 和 JUnit 4 测试--><依赖项><依赖><groupId>org.apache.maven.surefire</groupId><artifactId>surefire-junit47</artifactId><version>3.0.0-M4</version></依赖><依赖><groupId>org.apache.maven.surefire</groupId><artifactId>surefire-junit-platform</artifactId><version>3.0.0-M4</version></依赖></依赖项></插件>

    将 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 ---[信息][信息] -------------------------------------------------------[信息] T E S T S[信息] -------------------------------------------------------[信息] 运行 HelloJUnitTest[信息] 测试运行:1,失败:0,错误:0,跳过:0,经过的时间:0.059 秒 - 在 HelloJUnitTest 中[信息][信息] 结果:[信息][信息] 测试运行:1,失败:0,错误:0,跳过:0[信息][信息][信息] -------------------------------------------------------[信息] T E S T S[信息] -------------------------------------------------------[信息] 运行 DatabaseDrivenSpec[信息] 测试运行:3,失败:0,错误:0,跳过:0,经过的时间:0.171 秒 - 在 DatabaseDrivenSpec 中(...)[信息][信息] 结果:[信息][信息] 测试运行:39,失败:0,错误:0,跳过:0

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


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

    <!-- 仅当您想与 Spock 2 一起运行 JUnit 4 测试时才需要 --><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId><version>5.5.2</version><范围>测试</范围></依赖>

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

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

    Env

    • 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)
    

    • maven

    $ mvn -version
    Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
    Maven home: C:Program FilesJetBrainsIntelliJ IDEA 2019.2.3pluginsmavenlibmaven3
    Java version: 1.8.0_231, vendor: Oracle Corporation, runtime: C:Program FilesJavajdk1.8.0_231jre
    Default locale: zh_CN, platform encoding: GBK
    OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
    

    Problem

    I forked spockframework/spock-example add java test directory and HelloJUnitTest.java => sunzy/spock-exmaple

    the Spock Tests can execute,but JUnit Tests can't

    Snapshots

    • mvn clean test

    only spock tests!

    • mvn clean test -Dtest=HelloJUnitTest

    • JUnit Test had generate in target/test-classes*

    • mvn clean test -Dtest=HelloSpocSpec

    • mvn -X include test-clasess

    解决方案

    Okay, I have taken a look at your project. As you said, it is just the Spock sample project, upgraded to run Spock 2 tests. BTW, it still should be upgraded further, because in the current configuration compilation does not work with current Java versions, but that is off topic here, I am just mentioning it because I ran into a problem and then downgraded to Java 8 in order quickly reproduce your actual problem. The JUnit test's package name is not the problem either, even though the default package is always ugly, just like for the Spock tests.

    Spock 1.x is based on JUnit 4, but Spock 2.x is based on JUnit 5 platform. This is also the one automatically found by Surefire when analysing the project dependencies. If you want Surefire to run multiple engines in parallel, you need to configure the corresponding providers as plugin dependencies, as mentioned here.

    In your case, just add this to the 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>
    

    It also makes sense to explicitly add a test-scoped dependency to JUnit 4.12 or 4.13 to your POM because JUnit 4.12 is only a transitive dependency in your current POM. But later Spock 2 versions might remove that dependency because it is not really needed. I think that already happened with 2.0-M3. So be careful.

    After this change, Maven says:

    [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
    

    If you decide to upgrade from JUnit 4 to 5, maybe configuration gets easier for you because then both Spock and JUnit use the same provider. In that case please add a JUnit 5 dependency so your tests can import the corresponding test annotations and assertion methods.


    Update: After @khmarbaise commented on using vintage engine and me fully agreeing that it is the better solution, I want to show you how to do that instead of adding plugin dependencies to Surefire. (So you can delete those if you want to use this solution):

    <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>
    

    Why version 5.5.2 and not e.g. 5.6.2? In order to avoid version conflicts and subsequent warnings about vintage engine not finding tests in the Groovy directory. This is just because the POM in this sample project still uses a Spock 2.0-M1 BOM. As I said, it ought to be updated. But with this version it just works because it depends on the same JUnit 5 platform version as Spock in this configuration.

    BTW, now Maven executes the Spock tests first and then the JUnit 4 tests, so the log output for both would be in reverse order.

    这篇关于Maven/Surefire 无法在同一个项目中执行 Spock 和 JUnit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆