[英]How to avoid surefire test to be run in parallel
我這里有一個應用程序,其中單元測試的編寫方式無法並行運行。
由於這個原因,使用 maven 運行測試時,其中一些測試失敗。 我可以通過執行以下操作來驗證它們是否並行運行
System.out.println(System.currentTimeMillis() +">>> executing testXXX");
System.out.println(System.currentTimeMillis() +">>> finished testXXX");
在每個方法的開始和結束。 output 是:
1530602546964>>> executing testInstantiation
1530602547036<<< finished testInstantiation
1530602547042>>> executing testSimilarNamedResources
1530602547050>>> executing testTranslateWithMissingKey
1530602547051>>> executing testTryTranslateWithMissingKey
1530602547051<<< finished testTryTranslateWithMissingKey
1530602547051>>> executing testTranslationMapWithMissingKey
1530602547055>>> executing testSilentlyIgnoringExceptionTranslationMapWithMissingKey
1530602547055<<< finished testSilentlyIgnoringExceptionTranslationMapWithMissingKey
正如我們所看到的,在 testSimilarNamedResources 啟動后,其他一些測試也開始了。
我嘗試將 surefire 插件配置為不並行運行:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<!--parallel>false</parallel-->
<threadCount>1</threadCount>
<perCoreThreadCount>false</perCoreThreadCount>
</configuration>
</plugin>
</plugins>
</build>
但它仍然並行執行這些測試。 我使用-X
選項運行 mvn 以查看是否應用了我的配置並得到了這個 output:
$ mvn -X test | grep -iE "(parallel|threadcount)"
<parallel>${parallel}</parallel>
<parallelMavenExecution default-value="${session.parallel}"/>
<parallelOptimized default-value="true">${parallelOptimized}</parallelOptimized>
<parallelTestsTimeoutForcedInSeconds>${surefire.parallel.forcedTimeout}<parallelTestsTimeoutForcedInSeconds>
<parallelTestsTimeoutInSeconds>${surefire.parallel.timeout}<parallelTestsTimeoutInSeconds>
<perCoreThreadCount default-value="true">false</perCoreThreadCount>
<threadCount>0</threadCount>
<threadCountClasses default-value="0">${threadCountClasses}</threadCountClasses>
<threadCountMethods default-value="0">${threadCountMethods}</threadCountMethods>
<threadCountSuites default-value="0">${threadCountSuites}</threadCountSuites>
[DEBUG] (f) parallelMavenExecution = false
[DEBUG] (s) parallelOptimized = true
[DEBUG] (s) perCoreThreadCount = false
[DEBUG] (s) threadCount = 0
[DEBUG] (s) threadCountClasses = 0
[DEBUG] (s) threadCountMethods = 0
[DEBUG] (s) threadCountSuites = 0
我是否遺漏了插件配置中的某些內容?
更新:
我已經放棄了。 行為太奇怪了。 嘗試創建簡單示例沒有用。 這些測試不是並行運行的。 我沒有發現為什么會這樣。 我們將修改整個代碼,因此也會修改單元測試。 不再需要尋找解決方案,但它仍然讓我感到困惑,為什么它會顯示出這種奇怪的行為......
我建議您遵循以下指導:
從maven-surefire-plugin:2.18版本開始,您可以在JUnit測試的Java類(純測試類,Suite,Parameterized等)上應用JCIP批注@ net.jcip.annotations.NotThreadSafe,以便一次執行它線程實例。 該線程的名稱為maven-surefire-plugin @ NotThreadSafe,並在測試運行結束時執行。 https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html#Parallel_Test_Execution_and_Single_Thread_Execution
就像其他人說過的那樣,應該真正重寫它們,並且應該注釋絕對不能並行運行的測試。
對於您的插件定義,我建議您讓它並行運行,因為在現代計算機上它可能要快得多。
我的定義為:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<useUnlimitedThreads>true</useUnlimitedThreads>
<runOrder>random</runOrder>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<rerunFailingTestsCount>1</rerunFailingTestsCount>
<parallel>methods</parallel>
<forkedProcessExitTimeoutInSeconds>2</forkedProcessExitTimeoutInSeconds>
</configuration>
</plugin>
我只花了幾個小時來處理這個問題,最后通過將 forkCount 顯式設置為 1 來解決它。默認值應該是 1,但它確實不像它那樣工作。
我通過在幾個測試用例中打印正在運行的 JVM 的唯一名稱(使用 ManagementFactory.getRuntimeMXBean().getName())來確認這一點,每個測試用例都有自己的 class,以及 30 秒的 Thread.sleep() 調用。 在沒有顯式設置 forkCount 的情況下,sleep() 不會阻止其他測試用例的執行——教學測試顯然是同時運行的,而 getName() 返回的值明顯不同。 當我明確地將 forkCount 設置為 1 時,sleep() 調用會按預期阻止執行,並且 getName() 每次都返回相同的值。
此外,只是想添加 @NotThreadSafe 顯然也沒有按預期工作。 我先嘗試了一下,但沒有運氣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.