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

huangapple go评论64阅读模式
英文:

Maven/Surefire can't execute Spock and JUnit in the same project

问题

Env(环境)

  • java(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(Maven版本)
$ 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"

Problem(问题)

我从spockframework/spock-example分支派生出来,添加了Java测试目录和HelloJUnitTest.java => sunzy/spock-exmaple

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

Snapshots(快照)

  • mvn clean test

仅运行Spock测试!

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

  • mvn clean test -Dtest=HelloJUnitTest

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

  • JUnit测试已生成在target/test-classes目录下

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

  • mvn clean test -Dtest=HelloSpocSpec

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

  • mvn -X include test-clasess

英文:

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

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!

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

  • mvn clean test -Dtest=HelloJUnitTest

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

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

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

  • mvn clean test -Dtest=HelloSpocSpec

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

  • mvn -X include test-clasess

答案1

得分: 11

以下是您要翻译的内容:

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

<!-- language: xml -->

  &lt;plugin&gt;
    &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
    &lt;version&gt;3.0.0-M4&lt;/version&gt;
    &lt;configuration&gt;
      &lt;useFile&gt;false&lt;/useFile&gt;
      &lt;includes&gt;
        &lt;include&gt;**/*Test.java&lt;/include&gt;
        &lt;include&gt;**/*Spec.java&lt;/include&gt;
      &lt;/includes&gt;
    &lt;/configuration&gt;

    &lt;!-- Run Spock 2 and JUnit 4 tests in parallel --&gt;
    &lt;dependencies&gt;
      &lt;dependency&gt;
        &lt;groupId&gt;org.apache.maven.surefire&lt;/groupId&gt;
        &lt;artifactId&gt;surefire-junit47&lt;/artifactId&gt;
        &lt;version&gt;3.0.0-M4&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
        &lt;groupId&gt;org.apache.maven.surefire&lt;/groupId&gt;
        &lt;artifactId&gt;surefire-junit-platform&lt;/artifactId&gt;
        &lt;version&gt;3.0.0-M4&lt;/version&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;

  &lt;/plugin&gt;

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

<!-- language: xml -->

&lt;dependency&gt; &lt;!-- only required if you want to run JUnit 4 tests alongside Spock 2 --&gt;
  &lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
  &lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
  &lt;version&gt;5.5.2&lt;/version&gt;
  &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;

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.

英文:

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:

<!-- language: xml -->

  &lt;plugin&gt;
    &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
    &lt;version&gt;3.0.0-M4&lt;/version&gt;
    &lt;configuration&gt;
      &lt;useFile&gt;false&lt;/useFile&gt;
      &lt;includes&gt;
        &lt;include&gt;**/*Test.java&lt;/include&gt;
        &lt;include&gt;**/*Spec.java&lt;/include&gt;
      &lt;/includes&gt;
    &lt;/configuration&gt;

    &lt;!-- Run Spock 2 and JUnit 4 tests in parallel --&gt;
    &lt;dependencies&gt;
      &lt;dependency&gt;
        &lt;groupId&gt;org.apache.maven.surefire&lt;/groupId&gt;
        &lt;artifactId&gt;surefire-junit47&lt;/artifactId&gt;
        &lt;version&gt;3.0.0-M4&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
        &lt;groupId&gt;org.apache.maven.surefire&lt;/groupId&gt;
        &lt;artifactId&gt;surefire-junit-platform&lt;/artifactId&gt;
        &lt;version&gt;3.0.0-M4&lt;/version&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;

  &lt;/plugin&gt;

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

<!-- language: xml -->

&lt;dependency&gt; &lt;!-- only required if you want to run JUnit 4 tests alongside Spock 2 --&gt;
  &lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
  &lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
  &lt;version&gt;5.5.2&lt;/version&gt;
  &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;

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.

huangapple
  • 本文由 发表于 2020年7月28日 12:33:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63127069.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定