2014-03-29 3 views
7

테스트를 병렬로 실행하는 Gradle의 기능을 실험하고 있습니다. 내가 발견 한 주요 설정은 Test 작업의 maxParallelForks 속성입니다. 그 설정의 동작이 Executors.newFixedThreadPool 테스트를 실행하는 것과 비슷할 것으로 예상했습니다. 즉, 일정 수의 스레드 (Gradle의 경우 프로세스)가 동시에 실행되고 있습니다. 한 스레드가 작업을 완료 할 때마다 새 스레드가 풀에서 활성화됩니다.Gradle : 병렬로 실행 테스트 최적화

그러나 Gradle의 동작은 근본적으로 덜 적합합니다. Gradle은 테스트 클래스를 그룹의 maxParallelForks와 같은 숫자로 나눈 다음 Gradle이 각 그룹에 대해 프로세스를 생성하고 해당 프로세스가 병렬로 실행되도록합니다. 이 전략의 문제점은 명백합니다. 테스트 클래스에 필요한 시간에 따라 동적으로 실행을 조정할 수 없습니다.

예를 들어 5 개의 클래스가 있고 maxParallelForks이 2로 설정되어 있다고 가정합니다. 5 개의 클래스 중 느린 클래스가 있고 나머지는 상대적으로 빠릅니다. 이상적인 전략은 한 프로세스가 느린 프로세스를 실행하고 다른 프로세스는 빠른 프로세스를 처리하게하는 것입니다. 그러나 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 초가 될 수 있습니다.

그래서 사용자 정의 JUnit 러너를 사용하지 않고 Gradle에서이 동작을 최적화하는 간단한 방법이 있습니까?

대단히 감사합니다.

답변

1

이것은 Gradle 코드베이스를 변경해야만 최적화 할 수 있습니다.