Параллельно запускать тесты junit в сборке Maven? - PullRequest
108 голосов
/ 08 января 2009

Я использую JUnit 4.4 и Maven, и у меня большое количество длительных интеграционных тестов.

Когда речь идет о распараллеливании наборов тестов, есть несколько решений, которые позволяют мне запускать каждый метод тестирования в одном классе тестирования параллельно. Но все это требует, чтобы я так или иначе изменил тесты.

Я действительно думаю, что было бы намного более чистым решением параллельно запускать X различных классов тестирования в потоках X. У меня есть сотни тестов, поэтому я не особо беспокоюсь о потоке отдельных тестовых классов.

Есть ли способ сделать это?

Ответы [ 9 ]

70 голосов
/ 29 февраля 2012

Использовать плагин 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>
40 голосов
/ 08 июля 2009

Начиная с версии 4.7 теперь можно выполнять тесты параллельно без использования TestNG. На самом деле это стало возможным начиная с 4.6, но в 4.7 было сделано несколько исправлений, которые сделают его приемлемым вариантом. Вы также можете запустить параллельные тесты с пружиной, о которых вы можете прочитать здесь

10 голосов
/ 25 мая 2013

Вдохновленный экспериментальным JUnit ParallelComputer бегун Я создал свой собственный ParallelSuite и ParallelParameterized бегунов. Используя эти бегуны, можно легко распараллелить наборы тестов и параметризованные тесты.

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 {}
5 голосов
/ 02 января 2010

tempus-fugit предлагает что-то подобное, проверьте документы для деталей. Он основан на JUnit 4.7, и вы просто помечаете свой тест как @RunWith(ConcurrentTestRunner).

Приветствия

3 голосов
/ 04 июня 2011

Вы можете проверить библиотеку с открытым исходным кодом - Test Load Balancer . Он делает именно то, что вы просите - параллельно запускать разные тестовые классы. Это интегрируется на уровне ant-junit, поэтому вам не нужно менять тесты в любом случае. Я один из авторов библиотеки.

Кроме того, подумайте о том, чтобы не запускать их в потоках, поскольку вам может понадобиться песочница уровня процесса. Например, если вы используете БД в своих интеграционных тестах, вы не хотите, чтобы один тест провалился, потому что другой тест добавил некоторые данные в другой поток. В большинстве случаев тесты не написаны с учетом этого.

Наконец, как решили эту проблему до сих пор?

3 голосов
/ 08 января 2009

TestNG может сделать это (это был мой первый рефлекс - потом я увидел, что у вас уже много тестов).

Для JUnit, посмотрите на parallel-junit .

2 голосов
/ 26 декабря 2013

Вы можете запустить тесты параллельно, используя ParallelComputer, предоставленный самим Junit. Вот небольшой фрагмент для начала.

Class[] cls = { TestCase1.class, TestCase2.class };
Result result = JUnitCore.runClasses(ParallelComputer.classes(), cls);
List<Failure> failures = result.getFailures();

Это поможет, когда вам нужно запустить тесты из кода, поскольку он не зависит от Maven или каких-либо других инструментов управления сборкой.

Обратите внимание, что при этом все тестовые примеры будут выполняться параллельно, если у вас есть какие-либо зависимости между различными тестовыми примерами, это может привести к ложным срабатываниям. В любом случае, вам НЕ СЛЕДУЕТ проходить взаимозависимые тесты.

0 голосов
/ 08 апреля 2009

Вы можете попробовать Gridgain , которая позволит вам запустить распределение ваших тестов по вычислительной сетке.

0 голосов
/ 08 января 2009

Вы можете поменять ваш тест на TestNg за минуту (вам просто нужно изменить импорт), TestNG является лучшим в параллельном тестировании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...