Maven/Surefire не может выполнять Spock и JUnit в одном проекте

Окружение

  • Джава
$ 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"

Проблема

Я развил spockframework/spock-example, добавил тестовый каталог java и HelloJUnitTest.java =› sunzy/spock-exmaple

тесты Spock могут выполняться, но тесты JUnit не могут

Снимки

  • чистый тест mvn

только спок-тесты!

введите здесь описание изображения

  • чистый тест mvn -Dtest=HelloJUnitTest

введите здесь описание изображения

  • JUnit Test сгенерировал в целевых/тестовых классах*

введите здесь описание изображения

  • чистый тест mvn -Dtest=HelloSpocSpec

введите здесь описание изображения

  • mvn -X включает тестовый класс

person sunzy    schedule 28.07.2020    source источник
comment
Переместите модульный тест в пакет, а не в default.   -  person khmarbaise    schedule 28.07.2020
comment
@khmarbaise Я создал пакет в test/java и переместил в него тест, получил тот же результат   -  person sunzy    schedule 28.07.2020
comment
Конечно, Surefire/Failsafe могут выполнять тесты Spock и JUnit вместе, если они настроены правильно и макет вашего каталога соответствует стандарту Maven. Вы опубликовали впечатляющий объем информации, но не относящейся к делу: макет тестового исходного каталога и конфигурация плагина Maven. Хотя интересно увидеть результат в вашей ситуации, ввод, создающий этот вывод, был бы более интересным. Прежде чем я рассмотрю ваш проект GitHub, один вопрос: насколько вы опытны в Maven? Я хочу соответствующим образом скорректировать свой ответ.   -  person kriegaex    schedule 28.07.2020


Ответы (1)


Хорошо, я посмотрел ваш проект. Как вы сказали, это просто образец проекта Spock, обновленный для запуска тестов Spock 2. Кстати, его все равно нужно обновить, потому что в текущей конфигурации компиляция не работает с текущими версиями Java, но здесь это не по теме, я просто упоминаю об этом, потому что столкнулся с проблемой, а затем понизил версию до Java 8. чтобы быстро воспроизвести реальную проблему. Имя пакета теста JUnit также не является проблемой, даже несмотря на то, что пакет по умолчанию всегда уродлив, как и для тестов Spock.

Spock 1.x основан на JUnit 4, а Spock 2.x основан на платформе JUnit 5. Это также тот, который автоматически обнаруживается Surefire при анализе зависимостей проекта. Если вы хотите, чтобы Surefire запускала несколько движков параллельно, вам необходимо настроить соответствующих провайдеров в качестве зависимостей плагинов, как уже упоминалось здесь.

В вашем случае просто добавьте это в 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. Но более поздние версии Spock 2 могут удалить эту зависимость, поскольку она на самом деле не нужна. Я думаю, что это уже произошло с 2.0-М3. Так что будь осторожен.

После этого изменения 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 прокомментировал использование устаревшего движка и я полностью согласился с тем, что это лучшее решение, я хочу показать вам, как это сделать вместо добавления зависимостей плагинов в 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>

Почему версия 5.5.2, а не например. 5.6.2? Во избежание конфликтов версий и последующих предупреждений о том, что устаревший движок не находит тесты в каталоге Groovy. Это связано с тем, что POM в этом примере проекта по-прежнему использует спецификацию Spock 2.0-M1. Как я уже сказал, это должно быть обновлено. Но с этой версией это просто работает, потому что зависит от той же версии платформы JUnit 5, что и Spock в этой конфигурации.

Кстати, теперь Maven сначала выполняет тесты Spock, а затем тесты JUnit 4, поэтому вывод журнала для обоих будет в обратном порядке.

person kriegaex    schedule 28.07.2020
comment
Я бы предложил вместо этого использовать junit-jupiter-vintage и удалить зависимости от провайдера maven-surefire-plugin. И идти только через JUnit Jupiter... - person khmarbaise; 28.07.2020
comment
Вы правы, Карл Хайнц. Конечно, это было бы предпочтительнее, а также чище, чувствуя себя менее хакерским. Мое решение было слишком быстрым и слишком грязным, я просто возился с ним около двух минут. Я все еще новичок в Юпитере. - person kriegaex; 28.07.2020
comment
У меня было всего несколько минут, чтобы обновить ответ о винтажном движке JUnit 5. Еще раз спасибо, @khmarbaise. - person kriegaex; 29.07.2020
comment
Большое спасибо! surefire-junit47 и surefire-junit-platform не работают, но junit-vintage-engine работает - person sunzy; 29.07.2020
comment
Если первое решение не работает, вы допустили ошибку или изменили что-то еще. Я клонировал ваш проект прямо с GitHub и запускал там тесты. Оба решения работают. - person kriegaex; 29.07.2020