2014-03-29 121 views
7

我正在嘗試使用Gradle的並行運行測試功能。我發現的主要設置是Test任務的maxParallelForks屬性。我預計該設置的行爲類似於執行測試的Executors.newFixedThreadPool。即,固定數量的線程(Gradle情況下的進程)正在併發執行;只要一個線程完成工作,就會在池中激活一個新線程。Gradle:優化並行運行測試

但是,Gradle的行爲在不太理想的方式上有着根本的不同。它看起來像Gradle將測試類劃分爲等於組的maxParallelForks的數字,然後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亞軍?

非常感謝。

回答

1

這隻能通過更改Gradle代碼庫來優化。