В JUnit 4 и последних версиях плагина Maven Surefire появилась малоизвестная, но очень полезная функция: поддержка параллельного тестирования. Эта функция была давно в TestNG, но отсутствовала в JUnit. И теперь, если вы являетесь пользователем JUnit, вы также можете запускать свои тесты параллельно!
Параллельное выполнение тестов — это мощный способ ускорить ваши тесты. Хорошие автоматизированные тесты должны быть независимыми, изолированными и воспроизводимыми, что делает их идеальными кандидатами для одновременного запуска. Однако на практике не все тестовые классы разрабатываются с учетом параллелизма, и такие аспекты, как общие переменные изменяемого экземпляра, общий доступ к файлам или базам данных или использование встроенных веб-серверов, могут усложнить параллельное выполнение тестов. Тем не менее, параллельное выполнение тестов — это очень изящный трюк!
Посмотрим, как это работает. Начиная с JUnit 4.7, вы можете настроить Maven для параллельного запуска ваших тестов, как в TestNG. Следующая конфигурация будет запускать ваши методы тестирования параллельно:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <parallel>methods</parallel> </configuration></plugin>
Еще одна полезная уловка — параллельное выполнение тестовых классов, а не методов. Вы можете сделать это, установив элемент конфигурации в «классы» вместо «методы». Это может быть или быстрее в зависимости от количества тестовых классов, которые у вас есть, но также может быть более безопасным для некоторых тестовых случаев, не предназначенных для параллелизма:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <parallel>classes</parallel> </configuration></plugin>
Для более точного контроля над количеством потоков вы должны проверить библиотеку конфигурируемого параллельного компьютера (см. Также эту запись в блоге от автора библиотеки). (На моем двухъядерном ноутбуке это мало что изменило, но я ожидал более значительных различий на большом сервере сборки). Как только вы добавите эту зависимость к своим зависимостям (ее нет в стандартных репозиториях Maven, поэтому вы должны установить ее самостоятельно), вы можете запустить свои тесты параллельно, используя 4 потока, как показано здесь:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <parallel>methods</parallel> <threadCount>4</threadCount> </configuration></plugin>
Вы также можете настроить максимальное количество потоков на ядро ЦП, что обеспечивает немного большую гибкость при выполнении тестов на разных компьютерах:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <parallel>methods</parallel> <threadCount>4</threadCount> <perCoreThreadCount>true</perCoreThreadCount> </configuration></plugin>
‘UseUnlimitedThreads’ создаст столько потоков, сколько существует классов или методов, и попытается запустить их все одновременно. Это хорошо работает для модульных тестов, но когда я использовал эту опцию для веб-тестов, она быстро насыщала сервер.
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <parallel>classes</parallel> <useUnlimitedThreads>true</useUnlimitedThreads> </configuration></plugin>
Пробег будет варьироваться в зависимости от производительности вашей машины и характера ваших тестов, поэтому вы должны поэкспериментировать с различными конфигурациями и посмотреть, что лучше всего подходит для вас. Как правило, вы получите более значительные выгоды от более медленных тестов, связанных с вводом-выводом или доступом к сети / базе данных, таких как функциональные или веб-тесты, чем от большого количества небольших быстрых модульных тестов. Вот несколько примеров, которые я получил для веб-приложения среднего размера (работающего на моем MacBook Pro, который имеет 2 ядра):
Не используя ничего:
$ mvn verify:...Tests run: 150, Failures: 0, Errors: 0, Skipped: 0[INFO] [jetty:stop {execution: stop-jetty}][INFO] Stopping server 0[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESSFUL[INFO] ------------------------------------------------------------------------[INFO] Total time: 1 minute 2 seconds
Используя «методы»:
$ mvn verify:...Tests run: 150, Failures: 0, Errors: 0, Skipped: 0[INFO] [jetty:stop {execution: stop-jetty}][INFO] Stopping server 0[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESSFUL[INFO] ------------------------------------------------------------------------[INFO] Total time: 35 seconds
Используя «классы»:
$ mvn verify:...Tests run: 150, Failures: 0, Errors: 0, Skipped: 0[INFO] [jetty:stop {execution: stop-jetty}][INFO] Stopping server 0[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESSFUL[INFO] ------------------------------------------------------------------------[INFO] Total time: 32 seconds
Используя ‘оба’:
$ mvn verify:...Tests run: 150, Failures: 0, Errors: 0, Skipped: 0[INFO] [jetty:stop {execution: stop-jetty}][INFO] Stopping server 0[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESSFUL[INFO] ------------------------------------------------------------------------[INFO] Total time: 1 minutes 1 seconds
То, насколько «классы» или «методы» работают лучше всего, во многом зависит от количества тестовых классов, которые у вас есть, и количества методов в каждом классе. Для этих тестов «оба» не имели заметного эффекта.
Как упомянуто выше, в этих тестах и на моей машине увеличение threadCount имело небольшой эффект. Но это, опять же, будет зависеть от характера ваших тестов.
От http://weblogs.java.net/blog/johnsmart/archive/2010/07/06/running-junit-tests-parallel-maven