簡體   English   中英

如何避免surefire測試並行運行

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM