繁体   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