У меня проблема с попыткой настроить Maven для исключения некоторых категорий модульных тестов на основе нескольких профилей.
У меня есть две категории, определенные для модульного тестирования: SlowTest
для тех модульных тестов, выполнение которых занимает очень много времени, и WindowsTest
для тех модульных тестов, которые могут выполняться только в среде Windows.
У меня есть два профиля, определенные в файле pom.xml
моего проекта следующим образом:
<profiles>
<!-- Exclude any tests in `SlowTest` category when profile 'skipSlowTests' is specified. -->
<profile>
<id>skipSlowTests</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludedGroups>SlowTest.class</excludedGroups>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<!-- Skip any tests in 'WindowsTest' category when not running on Windows. -->
<profile>
<id>skipWindowsTests</id>
<activation>
<os><family>!windows</family></os>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludedGroups>WindowsTest.class</excludedGroups>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Так, например, когда я хочу запустить тесты и исключить любые медленные тесты, я могу выполнить mvn -PskipSlowTests test
. И если я хочу пропустить какие-либо тесты Windows, я могу выполнить mvn test
в ОС, отличной от Windows (или явно указать -PskipWindowsTests
в командной строке).
Проблема здесь в том, что когда оба профиля skipSlowTests
и skipWindowsTests
активированы, пропускаются только тесты Windows. Медленные тесты продолжают работать. Когда maven создает эффективный файл pom.xml
, он применяет профиль skipSlowTests
и настраивает maven-surefire-plugin
для исключения групп SlowTest.class
. Затем применяется профиль skipWindowsTests
, и это заменяет исключенные группы на WindowsTest.class
.
Я действительно хочу, чтобы исключенные группы были SlowTest.class,WindowsTest.class
, когда оба профиля активированы, но я не могу найти способ сделать это.
Я не могу видеть в maven добавление значения к свойству, например.
<properties>
<excludedGroups>IgnoreTest.class</excludedGroups>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludedGroups>${excludedGroups}</excludedGroups>
</configuration>
</plugin>
<profile>
<id>skipSlowTests</id>
<property>
<excludedGroups>${excludedGroups},SlowTest.class</excludedGroups>
</property>
...
</profile>
<profile>
<i>skipWindowsTests</id>
<property>
<excludedGroups>${excludedGroups},WindowsTest.class</excludedGroups>
</property>
...
</profile>
Это pom.xml
не работает, потому что есть рекурсия при присвоении значения свойству excludedGroups
.
И нет возможности настроить третий профиль (например, skipSlowTestsAndWindowsTests
), который активируется всякий раз, когда активируются и skipSlowTests
, и skipWindowsTests
.
Любые предложения здесь? Может быть, добавить отдельные фазы в maven-surefire-plugin
(одну для медленных тестов, одну для тестов Windows, одну для всех остальных) и использовать профили для определения, какие фазы выполняются?
Изменить №1
Я попытался создать отдельные фазы выполнения для maven-surefire-plugin
следующим образом:
<!-- By default, do not skip slow tests or windows tests -->
<properties>
<skipSlowTests>false</skipSlowTests>
<skipWindowsTests>false</skipWindowsTests>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<!-- Default execution will skip SlowTest and WindowsTest categories -->
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludedGroups>SlowTest,WindowsTest</excludedGroups>
</configuration>
</execution>
<!-- Slow Test execution will run the slow tests only (if not skipped) -->
<execution>
<id>slow-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>${skipSlowTests}</skip>
<groups>SlowTest</groups>
</configuration>
</execution>
<!-- Windows Test execution will run the windows tests only (if not skipped) -->
<execution>
<id>windows-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>${skipWindowsTests}</skip>
<groups>WindowsTest</groups>
</configuration>
</execution>
</executions>
</plugin>
<profiles>
<!-- Skip slow tests when skipSlowTests profile enabled -->
<profile>
<id>skipSlowTests</id>
<properties>
<skipSlowTests>true</skipSlowTests>
</properties>
</profile>
<!-- Skip windows tests when skipWindowsTests profile enabled -->
<profile>
<id>skipWindowsTests</id>
<properties>
<skipWindowsTests>true</skipWindowsTests>
</properties>
...
</profile>
</profiles>
Эта конфигурация будет запускать тесты в трех отдельных исполнениях: выполнение default-test
будет запускать все тесты, кроме медленных тестов и тестов Windows; выполнение slow-test
будет запускать только медленные тесты; и выполнение windows-test
будет запускать только тесты Windows. А если включены оба профиля skipSlowTests
и skipWindowsTests
, то и медленные тесты, и тесты windows будут пропущены.
Проблема здесь в том, что есть тест, помеченный как категориями SlowTest
, так и WindowsTest
:
@Test @Category({SlowTest.class,WindowsTest.class})
public void slowWindowsTestCase() { ... }
Когда включен только профиль skipSlowTests
, выполнение windows-test
все равно выполняется, а поскольку метод slowWindowsTestCase
помечен как тест Windows, он будет выполняться, даже если мы хотим пропустить медленные тесты. Точно так же этот тестовый пример также будет выполняться, когда включен только профиль skipWindowsTests
. Единственный способ пропустить этот тестовый пример — указать профили skipSlowTests
и skipWindowsTests
.
Я попытался изменить выполнение следующим образом:
<execution>
<id>slow-test</id>
...
<groups>SlowTest</groups>
<excludedGroups>WindowsTest</excludedGroups>
...
</execution>
<execution>
<id>windows-test</id>
...
<groups>WindowsTest</groups>
<excludedGroups>SlowTest</excludedGroups>
...
</execution>
Но теперь метод slowWindowsTestCase
никогда не выполняется.
Редактировать №2
И даже если бы я мог заставить выполнение тестов работать правильно, мне нужно было бы добавить зависимость от maven-surefire-plugin
, чтобы интерфейсы SlowTest
и WindowsTest
могли загружаться во время тестирования. Я поместил maven-surefire-plugin
в раздел pluginManagement
моего родительского POM, но любая зависимость, определенная для этого плагина, не может иметь область действия test
. В результате запустить тест вне модуля, определяющего интерфейсы SlowTest
и WindowsTest
, не получится. Я могу добавить зависимость области видимости test
для плагина в профилях, но это не будет охватывать случай, когда ни один профиль не активен.
<excludedGroups>
: это должен быть не типString
, а скорееArray
, например.<excludedGroups><excludedGroup>A</excludedGroup><excludedGroup>B</excludedGroup></excludedGroups>
. Теперь можно легко объединять элементы в один список. Вы можете запустить задачу для улучшения. - person dma_k   schedule 31.01.2014