简体   繁体   English

如何避免surefire测试并行运行

[英]How to avoid surefire test to be run in parallel

I have an application here where the unit tests are written in a way that they cannot be run in parallel.我这里有一个应用程序,其中单元测试的编写方式无法并行运行。

When running the tests with maven some of them fail for that reason.由于这个原因,使用 maven 运行测试时,其中一些测试失败。 I could verify that they are run in parallel by doing a我可以通过执行以下操作来验证它们是否并行运行

System.out.println(System.currentTimeMillis() +">>> executing testXXX");
System.out.println(System.currentTimeMillis() +">>> finished  testXXX");

at the start and end of each method.在每个方法的开始和结束。 The output is: 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   

As we can see after testSimilarNamedResources started, some other tests are started, too.正如我们所看到的,在 testSimilarNamedResources 启动后,其他一些测试也开始了。

I tried to configure the surefire plugin to not run in parallel:我尝试将 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>

But it still executes these tests in paralled.但它仍然并行执行这些测试。 I ran mvn with the -X option to see whether my configuration was applied and got this output:我使用-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                    

Do I miss something in the plugin configuration?我是否遗漏了插件配置中的某些内容?

UPDATE:更新:

I have given up.我已经放弃了。 The behaviour was too strange.行为太奇怪了。 Trying to create simple sample didn't work.尝试创建简单示例没有用。 Those tests were not run in parallel.这些测试不是并行运行的。 I didn't found out why this was the case here.我没有发现为什么会这样。 We will revamp the whole code and therefore also the unit tests.我们将修改整个代码,因此也会修改单元测试。 Not need to find a solution anymore, but it still puzzles me why it showed this strange behaviour…不再需要寻找解决方案,但它仍然让我感到困惑,为什么它会显示出这种奇怪的行为......

I would recomend you follow this guidance: 我建议您遵循以下指导:

Since of maven-surefire-plugin:2.18, you can apply the JCIP annotation @net.jcip.annotations.NotThreadSafe on the Java class of JUnit test (pure test class, Suite, Parameterized, etc.) in order to execute it in single Thread instance. 从maven-surefire-plugin:2.18版本开始,您可以在JUnit测试的Java类(纯测试类,Suite,Parameterized等)上应用JCIP批注@ net.jcip.annotations.NotThreadSafe,以便一次执行它线程实例。 The Thread has name maven-surefire-plugin@NotThreadSafe and it is executed at the end of the test run. 该线程的名称为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 https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html#Parallel_Test_Execution_and_Single_Thread_Execution

Like others have said they should really be rewritten and by exception the tests that absolutely cannot run in parallel should be annotated. 就像其他人说过的那样,应该真正重写它们,并且应该注释绝对不能并行运行的测试。

For your plugin definition i suggest you do let it run in parallel as it can be quite a bit faster on modern machines. 对于您的插件定义,我建议您让它并行运行,因为在现代计算机上它可能要快得多。

I have mine defined as: 我的定义为:

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

I just spent a few hours dealing with this and ended up resolving it by explicitly setting forkCount to 1. The default is supposed to be 1, but it sure doesn't act like it.我只花了几个小时来处理这个问题,最后通过将 forkCount 显式设置为 1 来解决它。默认值应该是 1,但它确实不像它那样工作。

I confirmed this by printing unique names for the running JVM (using ManagementFactory.getRuntimeMXBean().getName()) in a few test cases, each in their own class, along with 30 second Thread.sleep() calls.我通过在几个测试用例中打印正在运行的 JVM 的唯一名称(使用 ManagementFactory.getRuntimeMXBean().getName())来确认这一点,每个测试用例都有自己的 class,以及 30 秒的 Thread.sleep() 调用。 Without explicitly setting forkCount, sleep() did not block execution of other test cases - teach test clearly ran simultaneously, and getName() returned clearly different values.在没有显式设置 forkCount 的情况下,sleep() 不会阻止其他测试用例的执行——教学测试显然是同时运行的,而 getName() 返回的值明显不同。 When I explicitly set forkCount to 1, the sleep() calls blocked execution as expected and getName() returned the same value every time.当我明确地将 forkCount 设置为 1 时,sleep() 调用会按预期阻止执行,并且 getName() 每次都返回相同的值。

Also, just wanted to add @NotThreadSafe is apparently not working as intended either.此外,只是想添加 @NotThreadSafe 显然也没有按预期工作 I tried it first with no luck.我先尝试了一下,但没有运气。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM