我正在使用JUnit 4.4和Maven,並且我有大量的長時間運行的集成測試。在Maven構建中並行運行junit測試?
當談到並行化測試套件時,有幾個解決方案允許我在單個測試類中並行運行每個測試方法。但所有這些都要求我以這種或那種方式改變測試。
我真的認爲這將是一個更簡潔的解決方案,在X線程中並行運行X個不同的測試類。我有數百個測試,所以我並不在乎對單個測試類進行線程化。
有沒有辦法做到這一點?
我正在使用JUnit 4.4和Maven,並且我有大量的長時間運行的集成測試。在Maven構建中並行運行junit測試?
當談到並行化測試套件時,有幾個解決方案允許我在單個測試類中並行運行每個測試方法。但所有這些都要求我以這種或那種方式改變測試。
我真的認爲這將是一個更簡潔的解決方案,在X線程中並行運行X個不同的測試類。我有數百個測試,所以我並不在乎對單個測試類進行線程化。
有沒有辦法做到這一點?
從junit 4.7現在可以在不使用TestNG的情況下並行運行測試。實際上,從4.6開始就可以實現,但在4.7版本中有一些修復將會使它成爲一個可行的選擇。您也可以使用彈簧進行平行測試,您可以閱讀有關信息here
TestNG can do that(這是我的第一個反應 - 然後我看到你已經有很多測試用例)。
對於JUnit,請看parallel-junit。
不幸的是,這不是我問的問題的答案。 parallel-junit只能在單個測試類中運行。 TestNG也只能在一個類中運行,而我的測試不是TestNG測試。 – krosenvold 2009-01-08 11:42:33
@PlatinumAzure:我更新了鏈接。我不知道這個項目是如何維護的。另一個問題最近被問到[在幾臺機器上分發junit測試執行](http://stackoverflow.com/questions/10690587/running-parallel-junit-tests-on-multiple-remote-machines)。 – philant 2012-05-24 07:16:04
您可以在一分鐘內將您的測試更改爲TestNg測試(您只需更改導入),TestNG是最好的並行測試。
你可以試試Gridgain,它可以讓你在計算網格上運行你的測試。
我嘗試過GridGain解決方案,並遇到兩個主要問題。首先,你必須告訴GridGain從網格任務的類路徑中排除GridGain也使用的任何東西,例如Spring和許多Apache Commons的東西。其次,網絡類加載雖然是一個絕妙的想法,但不適用於想要搜索類路徑的庫,例如Spring – 2010-12-19 23:24:14
tempus-fugit提供了類似的內容,請查看文檔以瞭解詳細信息。它依賴於JUnit 4.7,您只需將您的測試標記爲@RunWith(ConcurrentTestRunner)
即可。
乾杯
您可以檢查出的開源庫 - Test Load Balancer。它完全符合你的要求 - 並行運行不同的測試類。這集成在ant-junit級別,所以你不必改變你的測試。我是圖書館的作者之一。
另外,請考慮不要在線程中運行它們,因爲您可能需要一個進程級別的沙箱。例如,如果您在集成測試中擊中數據庫,則不希望一次測試失敗,因爲另一次測試會在另一個線程中添加一些數據。大多數情況下,測試不會寫在這裏。
最後,到現在爲止如何解決了這個問題?
使用Maven插件:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>5</threadCount>
</configuration>
</plugin>
</plugins>
</build>
通過JUnit的實驗ParallelComputer亞軍啓發我已經建立了自己的ParallelSuite和ParallelParameterized亞軍。使用這些跑步者可以輕鬆地並行測試套件和參數化測試。
ParallelSuite.java
public class ParallelSuite extends Suite {
public ParallelSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
super(klass, builder);
setScheduler(new RunnerScheduler() {
private final ExecutorService service = Executors.newFixedThreadPool(4);
public void schedule(Runnable childStatement) {
service.submit(childStatement);
}
public void finished() {
try {
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
});
}
}
ParallelParameterized。java
public class ParallelParameterized extends Parameterized {
public ParallelParameterized(Class<?> arg0) throws Throwable {
super(arg0);
setScheduler(new RunnerScheduler() {
private final ExecutorService service = Executors.newFixedThreadPool(8);
public void schedule(Runnable childStatement) {
service.submit(childStatement);
}
public void finished() {
try {
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
});
}
}
用法很簡單。只需將@RunWith註釋值賦予其中一個並行*類。
@RunWith(ParallelSuite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {}
您可以使用由Junit自身提供的ParallelComputer並行運行測試。這裏有一個小小的部分讓你開始。
Class[] cls = { TestCase1.class, TestCase2.class };
Result result = JUnitCore.runClasses(ParallelComputer.classes(), cls);
List<Failure> failures = result.getFailures();
當您需要從代碼運行測試時,這將有所幫助,因爲它不依賴於Maven或任何其他構建管理工具。
請注意,這將並行運行所有測試用例,如果您在不同測試用例之間存在任何依賴關係,可能會導致誤報。無論如何你都不應該有相互依存的測試。
鏈接頁面顯示「對於大多數雙核解決方案來說,使用並行線程運行目前永遠不會比運行非線程更快」。那仍然是這樣嗎? – Raedwald 2011-04-04 14:00:33
我會認爲,如果你的測試做任何IO,他們仍然會受益。例如,如果你的單元測試更像集成測試並且碰到數據庫,那麼並行運行應該加速它們。 – Dave 2011-05-04 18:46:41