Запуск тестов JUnit параллельно с Maven

Запуск JUnit-тестов параллельно с Maven

1. Вступление

Хотя серийное выполнение тестов в большинстве случаев работает нормально. Иногда нам может понадобиться ускорить процесс. В этих ситуациях могут помочь параллельные тесты.

JUnit 4.7 and later versions make it possible to execute tests in parallel using Maven’s Surefire Plugin. Короче говоря, Surefire предоставляет два способа параллельного выполнения тестов:

  • Первый подход использует многопоточность внутри одного процесса JVM

  • В то время как второй подход использует несколько процессов JVM

В этом руководстве мы расскажем, как настроить Surefire для параллельного запуска тестов JUnit внутри одного процесса JVM. Затем мы увидим, как запускать тесты параллельно в многомодульном проекте Maven.

2. Maven Зависимости

Начнем с импорта необходимых зависимостей. We’ll need to use JUnit 4.7 or later along with Surefire 2.16 or later:с


    junit
    junit
    4.12
    test

    org.apache.maven.plugins
    maven-surefire-plugin
    2.22.0

3. Выполнение параллельных тестов

Чтобы запустить тест параллельно, мы должны использовать средство запуска тестов, расширяющееorg.junit.runners.ParentRunner.

Однако даже тесты, в которых явно не объявляется средство выполнения тестов, работают, поскольку средство выполнения по умолчанию расширяет этот класс.

Затем, чтобы продемонстрировать выполнение параллельных тестов, мы будем использовать набор тестов с двумя тестовыми классами, каждый из которых имеет несколько методов. Фактически, подойдет любая стандартная реализация набора тестов JUnit.

3.1. Использование параллельного параметра

Во-первых, давайте включим параллельное поведение в Surefire с помощью спараметраparallel . It states the level of granularity at which we would like to apply parallelism.

Возможные значения:

  • methods –  запускает методы тестирования в отдельных потоках

  • classes – запускает тестовые классы в отдельных потоках

  • classesAndMethods – запускает классы и методы в отдельных потоках

  • suites – rсьютов параллельно

  • suitesAndClasses –  запускает наборы и классы в отдельных потоках

  • suitesAndMethods – создает отдельные потоки для классов и для методов

  • all – запускает наборы, классы, а также методы в отдельных потоках

В нашем примере мы используемall:


    all

Во-вторых, давайте определим общее количество потоков, которые мы хотим создать в Surefire. Мы можем сделать это двумя способами:

ИспользуяthreadCount, который определяет максимальное количество потоков, которые Surefire создаст:

10

Или используя параметрuseUnlimitedThreads, где создается один поток для каждого ядра процессора:

true

По умолчаниюthreadCount на каждое ядро ​​ЦП. Мы можем использовать параметрperCoreThreadCount, чтобы включить или отключить это поведение:

true

3.2. Использование ограничений на количество потоков

Теперь допустим, что мы хотим определить количество создаваемых потоков на уровне метода, класса и набора. We can do this with the threadCountMethods, threadCountClasses and threadCountSuites parameters.с

Давайте объединим эти параметры сthreadCount из предыдущей конфигурации: _ _

2
2
6

Поскольку мы использовалиall вparallel, we, мы определили количество потоков для методов, наборов, а также классов. Однако определять листовой параметр не обязательно. Surefire определяет количество потоков, которые следует использовать в случае, если параметры листьев опущены.

Например, еслиthreadCountMethods опущено, нам просто нужно убедиться, чтоthreadCount>threadCountClasses  +threadCountSuites.

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

Мы также можем применить ограничения на количество потоков в таких случаях:

true
2

3.3. Установка таймаутов

Иногда нам может потребоваться убедиться, что выполнение теста ограничено по времени.

To do that we can use the parallelTestTimeoutForcedInSeconds parameter. Это прервет выполнение текущих потоков и не выполнит ни один из потоков в очереди по истечении тайм-аута:

5

Другой вариант - использоватьparallelTestTimeoutInSeconds.

В этом случае только потоки в очереди будут остановлены для выполнения:

3.5

Тем не менее, с обоими вариантами тесты завершатся с сообщением об ошибке по истечении времени ожидания.

3.4. Предостережения

Surefire вызывает статические методы, аннотированные@Parameters,@BeforeClass и@AfterClass в родительском потоке. Таким образом, убедитесь, что проверили потенциальные несоответствия памяти или условия гонки, прежде чем запускать тесты параллельно.

Кроме того, тесты, которые изменяют общее состояние, определенно не подходят для параллельной работы.

4. Выполнение теста в многомодульных проектах Maven

До сих пор мы сосредоточились на параллельном запуске тестов в модуле Maven.

Но допустим, у нас есть несколько модулей в проекте Maven. Поскольку эти модули построены последовательно, тесты для каждого модуля также выполняются последовательно.

We can change this default behavior by using Maven’s -T parameter which builds modules in parallel. Это можно сделать двумя способами.

Мы можем указать точное количество потоков, которые будут использоваться при создании проекта:

mvn -T 4 surefire:test

Или используйте переносную версию и укажите количество потоков, создаваемых для каждого ядра ЦП:

mvn -T 1C surefire:test

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

5. Заключение

Подводя итог, мы начали с включения многопоточного поведения и определения степени параллелизма с помощью параметраparallel. Впоследствии мы применили ограничения на количество потоков, которые Surefire должен создать. Позже мы устанавливаем параметры времени ожидания для контроля времени выполнения теста.

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

Как всегда, здесь представлен кодavailable on GitHub.