Параллельный запуск тестов junit в сборке Maven?

StackOverflow https://stackoverflow.com/questions/423627

  •  05-07-2019
  •  | 
  •  

Вопрос

Я использую 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 , который позволяет запускать распределите свои тесты по вычислительной сетке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top