Подтвердить что ты не робот

Запуск тестов junit параллельно в сборке Maven?

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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

Использовать плагин 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>

Ответ 3

Вдохновленный экспериментатором 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 {}

Ответ 4

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

Приветствия

Ответ 6

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

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

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

Ответ 7

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

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

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

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

Ответ 8

Другой выбор: Punner, новый параллельный раннер Junit и плагин Maven. Вам не нужно менять код, скопируйте его в свой файл pom.xml:

<!-- Disable default surefire based testing -->
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.20</version>
  <configuration>
    <skip>true</skip>
  </configuration>
</plugin>

<plugin>
  <groupId>com.github.marks-yag</groupId>
  <artifactId>punner-maven-plugin</artifactId>
  <version>${version}</version>
  <configuration>
  </configuration>
  <executions>
    <execution>
      <id>test</id>
      <phase>test</phase>
      <goals>
        <goal>test</goal>
      </goals>
    </execution>
  </executions>
</plugin>

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

Punner уменьшит количество выводов консоли mvn следующим образом:

[INFO] --- punner-maven-plugin:0.9.13:test (test) @ ipc ---
[INFO] Punner report directory: /Users/guile/workspace/ipc/target/punner-reports
[INFO]
[INFO] com.github.yag.ipc.IPCTest.testConnectionHandler.............. PASSED
[INFO] com.github.yag.ipc.IPCTest.testSequence....................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testPartialContent................. PASSED
[INFO] com.github.yag.ipc.IPCTest.testResponseContent................ PASSED
[INFO] com.github.yag.ipc.IPCTest.testPingPong....................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testServerClose.................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testServerSideHeartbeatTimeout..... PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientSideHeartbeatTimeout..... PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientSideHeartbeat............ PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientReconnect................ PASSED
[INFO]
[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.952 sec, Time saved: 25.919 sec.

Punner обеспечивает надежный вывод, вы также можете получить необработанные данные журнала и отчет в формате уценки из каталога отчетов:

➜  ipc git:(develop) ll target/punner-reports
total 104
-rw-r--r--   1 guile  staff    11K Oct 15 23:07 TEST-com.github.yag.ipc.IPCTest.xml
-rw-r--r--   1 guile  staff   298B Oct 15 23:07 com.github.yag.ipc.IPCTest.txt
drwxr-xr-x  12 guile  staff   384B Oct  8 00:50 logs
-rw-r--r--   1 guile  staff    33K Oct 15 23:07 report.md

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

Punner пока не поддерживает некоторые дополнительные функции. Я очень рад, что вы могли бы попробовать и дать мне обратную связь.

Ответ 9

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

Ответ 10

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