Параллельный запуск тестов junit в сборке Maven?
Вопрос
Я использую JUnit 4.4 и Maven, и у меня есть большое количество длительных интеграционных тестов.
Когда дело доходит до распараллеливания наборов тестов, есть несколько решений, которые позволяют мне запускать каждый тестовый метод в одном тестовом классе параллельно.Но все это требует, чтобы я так или иначе изменил тесты.
Я действительно думаю, что было бы гораздо более чистым решением параллельно запускать X разных тестовых классов в X потоках.У меня есть сотни тестов, поэтому я на самом деле не забочусь о потоковой передаче отдельных тестовых классов.
Есть ли какой-нибудь способ сделать это?
Решение 2
Начиная с версии 4.7 теперь можно запускать тесты параллельно без использования TestNG. На самом деле это стало возможным начиная с 4.6, но в 4.7 было сделано несколько исправлений, которые сделают его приемлемым вариантом. Вы также можете запустить параллельные тесты с пружиной, которые вы можете прочитать о здесь
Другие советы
Используйте плагин maven:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>5</threadCount>
</configuration>
</plugin>
</plugins>
</build>
Вдохновленный экспериментальным проектом JUnit Параллельный компьютер бегун, которого я построил сам. Параллельный набор и Параллельпараметризованный бегуны.Используя эти раннеры, можно легко распараллеливать наборы тестов и параметризованные тесты.
ParallelSuite.java
public class ParallelSuite extends Suite {
public ParallelSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
super(klass, builder);
setScheduler(new RunnerScheduler() {
private final ExecutorService service = Executors.newFixedThreadPool(4);
public void schedule(Runnable childStatement) {
service.submit(childStatement);
}
public void finished() {
try {
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
});
}
}
ParallelParameterized.java
public class ParallelParameterized extends Parameterized {
public ParallelParameterized(Class<?> arg0) throws Throwable {
super(arg0);
setScheduler(new RunnerScheduler() {
private final ExecutorService service = Executors.newFixedThreadPool(8);
public void schedule(Runnable childStatement) {
service.submit(childStatement);
}
public void finished() {
try {
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
});
}
}
Использование простое.Просто измени @RunWith значение аннотации к одному из этих Параллельный* классы.
@RunWith(ParallelSuite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {}
темпус-фугит предлагает что-то подобное, подробности смотрите в документации.Он основан на JUnit 4.7, и вы просто отмечаете свой тест как @RunWith(ConcurrentTestRunner)
.
Ваше здоровье
TestNG может сделать это (это был мой первый рефлекс - потом я увидел, что у вас уже много тестов). Р>
Что касается JUnit, посмотрите parallel-junit . Р>
Вы можете проверить библиотеку с открытым исходным кодом - Test Load Balancer . Он делает именно то, что вы просите - параллельно запускать разные тестовые классы. Это интегрируется на уровне ant-junit, поэтому вам не нужно менять тесты в любом случае. Я один из авторов библиотеки.
Кроме того, подумайте о том, чтобы не запускать их в потоках, поскольку вам может понадобиться песочница на уровне процесса. Например, если вы бьете по БД в своих интеграционных тестах, вы не хотите, чтобы один тест не прошел, потому что другой тест добавил некоторые данные в другой поток. В большинстве случаев тесты не написаны с учетом этого.
Наконец, как решили эту проблему до сих пор?
Вы можете запустить тесты параллельно, используя ParallelComputer, предоставленный самим Junit. Вот небольшой фрагмент, чтобы вы начали.
Class[] cls = { TestCase1.class, TestCase2.class };
Result result = JUnitCore.runClasses(ParallelComputer.classes(), cls);
List<Failure> failures = result.getFailures();
Это поможет, когда вам нужно запустить тесты из кода, поскольку он не зависит от Maven или каких-либо других инструментов управления сборкой.
Обратите внимание, что при этом все тестовые примеры будут выполняться параллельно, если у вас есть зависимости между различными тестовыми примерами, это может привести к ложным срабатываниям. В любом случае, вы НЕ ДОЛЖНЫ иметь взаимозависимые тесты.
Вы можете поменять ваш тест на TestNg за минуту (вам просто нужно изменить импорт), TestNG является лучшим в параллельном тестировании.
Вы можете попробовать Gridgain , который позволяет запускать распределите свои тесты по вычислительной сетке. Р>