如何避免并行运行 Surefire 测试

rad*_*lan 7 java junit maven maven-surefire-plugin

我这里有一个应用程序,其中单元测试的编写方式无法并行运行。

\n\n

当使用 Maven 运行测试时,其中一些测试会因为这个原因而失败。\n我可以通过执行以下操作来验证它们是否并行运行

\n\n
System.out.println(System.currentTimeMillis() +">>> executing testXXX");\nSystem.out.println(System.currentTimeMillis() +">>> finished  testXXX");\n
Run Code Online (Sandbox Code Playgroud)\n\n

在每个方法的开始和结束处。\n输出为:

\n\n
1530602546964>>> executing testInstantiation                                                                                                                         \n1530602547036<<< finished  testInstantiation                                                                                                                         \n1530602547042>>> executing testSimilarNamedResources                                                                                                                 \n1530602547050>>> executing testTranslateWithMissingKey                                                                                                               \n1530602547051>>> executing testTryTranslateWithMissingKey                                                                                                            \n1530602547051<<< finished  testTryTranslateWithMissingKey                                                                                                            \n1530602547051>>> executing testTranslationMapWithMissingKey                                                                                                          \n1530602547055>>> executing testSilentlyIgnoringExceptionTranslationMapWithMissingKey                                                                                 \n1530602547055<<< finished  testSilentlyIgnoringExceptionTranslationMapWithMissingKey   \n
Run Code Online (Sandbox Code Playgroud)\n\n

正如我们所看到的,在 testSimilarNamedResources 启动后,其他一些测试也启动了。

\n\n

我尝试将 Surefire 插件配置为不并行运行:

\n\n
<build>                                                                                                                                                           \n   <plugins>\n     <plugin>\n       <groupId>org.apache.maven.plugins</groupId>\n       <artifactId>maven-surefire-plugin</artifactId>\n       <version>2.22.0</version>\n       <configuration>\n         <!--parallel>false</parallel-->\n         <threadCount>1</threadCount>\n         <perCoreThreadCount>false</perCoreThreadCount>\n       </configuration>\n     </plugin>\n   </plugins>\n</build>\n
Run Code Online (Sandbox Code Playgroud)\n\n

但它仍然并行执行这些测试。\n我运行 mvn 并选择-X查看我的配置是否已应用并得到以下输出:

\n\n
$ mvn -X test | grep -iE "(parallel|threadcount)"                                                                                                                \n  <parallel>${parallel}</parallel>                                                                                                                               \n  <parallelMavenExecution default-value="${session.parallel}"/>                                                                                                  \n  <parallelOptimized default-value="true">${parallelOptimized}</parallelOptimized>                                                                               \n  <parallelTestsTimeoutForcedInSeconds>${surefire.parallel.forcedTimeout}<parallelTestsTimeoutForcedInSeconds>                                                   \n  <parallelTestsTimeoutInSeconds>${surefire.parallel.timeout}<parallelTestsTimeoutInSeconds>                                                                     \n  <perCoreThreadCount default-value="true">false</perCoreThreadCount>                                                                                            \n  <threadCount>0</threadCount>                                                                                                                                   \n  <threadCountClasses default-value="0">${threadCountClasses}</threadCountClasses>                                                                               \n  <threadCountMethods default-value="0">${threadCountMethods}</threadCountMethods>                                                                               \n  <threadCountSuites default-value="0">${threadCountSuites}</threadCountSuites>                                                                                  \n[DEBUG]   (f) parallelMavenExecution = false                                                                                                                     \n[DEBUG]   (s) parallelOptimized = true                                                                                                                           \n[DEBUG]   (s) perCoreThreadCount = false                                                                                                                         \n[DEBUG]   (s) threadCount = 0                                                                                                                                    \n[DEBUG]   (s) threadCountClasses = 0                                                                                                                             \n[DEBUG]   (s) threadCountMethods = 0                                                                                                                             \n[DEBUG]   (s) threadCountSuites = 0                    \n
Run Code Online (Sandbox Code Playgroud)\n\n

我是否遗漏了插件配置中的某些内容?

\n\n

更新:

\n\n

我已经放弃了。这行为太奇怪了。尝试创建简单的示例没有成功。这些测试不是并行运行的。我不明白为什么这里会出现这种情况。\n我们将修改整个代码,因此也修改单元测试。不再需要找到解决方案,但它仍然让我困惑为什么它表现出这种奇怪的行为\xe2\x80\xa6

\n

Mor*_*sUK 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>
Run Code Online (Sandbox Code Playgroud)