Gradle: оптимизация параллельных тестов
я экспериментирую с возможностью Gradle для запуска тестов параллельно. Главный параметр я нашел это maxParallelForks
собственность тест задач. Я ожидал, что поведение этой настройки будет похоже на наличие Executors.newFixedThreadPool
для выполнения тестов. А именно, фиксированное количество потоков (процессов в случае Gradle) выполняется одновременно; всякий раз, когда один поток завершает работу, новый активируется в пуле.
например, предположим, что у вас есть 5 классов и maxParallelForks
установлено значение 2. Среди пяти классы, есть медленный, а остальные относительно быстрые. Идеальной стратегией было бы позволить одному процессу выполнить медленный, а другому-быстрый. Однако Gradle группирует медленный вместе с одним или двумя быстрыми и порождает два процесса для выполнения двух групп классов, что, безусловно, менее оптимально, чем идеальный случай.
вот простая демонстрация.
медленный класс:
class DemoTest {
@Test
void one() {
Thread.sleep( 5000 )
println System.getProperty('org.gradle.test.worker') + ": " + new Date().format('HH:mm:ss')
assert 1 == 1
}
@Test
void two() {
Thread.sleep( 5000 )
println System.getProperty('org.gradle.test.worker') + ": " + new Date().format('HH:mm:ss')
assert 1 == 1
}
}
быстрые классы (DemoTest2-4, с идентичное тело класса):
class DemoTest2 {
@Test
void one() {
Thread.sleep( 1000 )
println System.getProperty('org.gradle.test.worker') + ": " + new Date().format('HH:mm:ss')
assert 1 == 1
}
@Test
void two() {
Thread.sleep( 1000 )
println System.getProperty('org.gradle.test.worker') + ": " + new Date().format('HH:mm:ss')
assert 1 == 1
}
}
все классы находятся в пакете junit
, который, оказывается, то же самое имя, что и знаменитый тестовый фреймворк : -)
вот возможный выход:
junit.DemoTest2 > one STANDARD_OUT
2: 14:54:00
junit.DemoTest2 > two STANDARD_OUT
2: 14:54:01
junit.DemoTest4 > one STANDARD_OUT
2: 14:54:02
junit.DemoTest4 > two STANDARD_OUT
2: 14:54:03
junit.DemoTest > one STANDARD_OUT
3: 14:54:04
junit.DemoTest > two STANDARD_OUT
3: 14:54:09
junit.DemoTest3 > one STANDARD_OUT
3: 14:54:10
junit.DemoTest3 > two STANDARD_OUT
3: 14:54:11
junit.DemoTest5 > one STANDARD_OUT
3: 14:54:12
junit.DemoTest5 > two STANDARD_OUT
3: 14:54:13
как вы можете видеть, медленные класс DemoTest
группируется с двумя быстрыми классами. Общее время выполнения составляет около 13 секунд, что могло бы составлять 10 секунд, если бы быстрые классы были сгруппированы вместе.
Итак, есть ли простой способ, чтобы оптимизировать этот поведение в Gradle без обращения к пользовательскому JUnit runner?
спасибо.