JUnit 和 Surefire 并行测试 - ForkCount 和 ThreadCount

Posted

技术标签:

【中文标题】JUnit 和 Surefire 并行测试 - ForkCount 和 ThreadCount【英文标题】:JUnit and Surefire Parallel Tests - ForkCount & ThreadCount 【发布时间】:2016-01-04 10:26:38 【问题描述】:

我正在使用 Surefire 插件在 Selenium Grid 上运行 Selenium 测试以执行测试。 就我的测试细分而言,我有几个课程,其中一些有 1 个测试,有的不止一个测试。

所以在我的 Grid 上,我有 30 个 chrome Web 驱动程序,我想在所有类中并行执行所有测试。

我已经阅读了如何使用我设置为的parallel 参数来执行此操作:

            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.17</version>
                <configuration>
                    <includes>
                        <include>$testSuite</include>
                    </includes>
                    <parallel>all</parallel>
                    <useSystemClassLoader>false</useSystemClassLoader>
                    <perCoreThreadCount>false</perCoreThreadCount>
                    <threadCount>20</threadCount>
                    <browser>$browser_type</browser>
                </configuration>
            </plugin>

然而,这似乎并没有填满我可用的所有 Chrome 网络驱动程序。

如果我然后使用forkCount,例如:

<forkCount>20</forkCount>
<reuseForks>true</reuseForks>

然后,当测试执行第一次开始时,所有的网络驱动程序都被填满了,但是它很快就开始下降并一次只运行一个。

所以我的问题:

forkCount和threadCount有没有关系 我需要做些什么才能真正实现并行运行吗?

谢谢。

【问题讨论】:

您是否在测试中使用@NotThreadSafe?你需要的一切都在这里maven.apache.org/surefire/maven-surefire-plugin/examples/… 否 - 不使用 @NotThreadSafe selenium 脚本设计为并行运行?否则所有线程操作都将在单个 chrome 浏览器中发生。 您将需要编写一个自定义的 junit 运行器来正确地将测试分配给不同的并行线程并自己清理。它不是开箱即用的,一开始它似乎可以这样做,但线程不会被重用。 【参考方案1】:

您必须提供明确的 junit 测试提供程序:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-junit47</artifactId>
            <version>2.18.1</version>
        </dependency>
    </dependencies>
    <configuration>
        <parallel>all</parallel>
        <useUnlimitedThreads>true</useUnlimitedThreads>
        <useSystemClassLoader>false</useSystemClassLoader>
        <includes>
            <include>$testSuite</include>
        </includes>
        <systemPropertyVariables>
            <browser>$browser_type</browser>
        </systemPropertyVariables>
     </configuration>
</plugin>

您应该使用 JUnit 4.7+,因为旧版本不能正确地进行并行测试。

如果您的测试不影响 JVM 运行时(通常情况并非如此),您也可以省略与 fork 相关的参数。

或者将您的测试迁移到 TestNG - 它是一个更优雅的框架,它更适合并行测试,然后是 JUnit (imo)。

【讨论】:

surefire-junit47 如果您使用 junit 4.8+ 并在配置中使用 参数,则会自动选择:maven.apache.org/surefire/maven-surefire-plugin/examples/… @Ardesco - 真/假。是的,因为你是对的。 false,因为 OP 不使用组。但是显式声明保证将使用正确的测试提供者。 在插件中使用依赖没有任何区别。 (我使用的是 jUnit 4.11) 正如我之前写的 - 你应该使用 JUnit 4.7+,因为旧版本不能正确地进行并行测试(通过 surefire 插件)。考虑更新 JUnit 4.11 => 4.7。 4.11 不是比 4.7 更新吗? (11 > 7 )?【参考方案2】:

并行运行测试的配置太多了。

根据文档:

forkCount

参数forkCount 定义了 Surefire 将同时生成以执行测试的最大 JVM 进程数。它支持与 maven-core 中的 -T 相同的语法:如果您以 C 终止该值,则该值将乘以系统中可用 CPU 内核的数量。例如,四核系统上的forkCount=2.5C 将导致分叉多达十个执行测试的并发 JVM 进程。

...

默认设置为forkCount=1/reuseForks=true,这意味着Surefire创建一个新的JVM进程来执行一个maven模块中的所有测试。

线程数

当使用reuseForks=true 和大于一的forkCount 值时,测试类会被一个接一个地交给分叉的进程。因此,parallel=classes 不会改变任何东西。但是,你可以使用parallel=methods:类在forkCount并发进程中执行,然后每个进程可以使用threadCount线程并行执行一个类的方法。

据我所知,threadCount 就像每个 fork 的子线程。

您可以调整这些参数以提高您的测试性能,例如,您可以:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.17</version>
    <configuration>
         <includes>
              <include>$testSuite</include>
         </includes>
         <parallel>all</parallel>
         <useSystemClassLoader>false</useSystemClassLoader>
         <perCoreThreadCount>false</perCoreThreadCount>
         <forkCount>2.0C</forkCount>
         <reuseForks>true</reuseForks>
         <threadCount>20</threadCount>
         <browser>$browser_type</browser>
    </configuration>
</plugin>

您可以在其网站上找到更多详细信息:

https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html

【讨论】:

我已经对这些进行了试验,但是我得到的问题是我的所有 chrome 驱动程序都没有被填充,即使我对其进行了足够的测试。 @userMod2 似乎是您的测试用例设置的问题,而不是您希望同时运行它们的方式。例如,您可以删除所有并行性并检查您的驱动程序是否已满,如果没有,那么您还有另一个问题。据我所知,您的 @Before@BeforeClass 注释方法中可能存在问题,您是否在此处加载驱动程序? 我删除了所有并行配置,它只在一个 Web 驱动程序中运行,所以我的配置正在使用中。我的代码中也没有 Before 或 @BeforeClass 方法 @userMod2 似乎您遇到了不同的问题,并且与您的问题所要求的并发性无关。您的问题旨在同时运行您的测试,这里的答案解决了这个问题。如果你说你没有@Before@BeforeClass,那么我认为你没有很好地配置你的测试用例设置。使用这两个注释将帮助您设置您想要的任何内容(例如您正在测试的驱动程序),一旦您配置了它,您就可以同时运行它们。除非您在每种测试方法中单独加载每个驱动程序,否则您将遇到问题 @userMod2 因此,我建议您使用单元测试样本创建另一个问题并询问您面临的问题。顺便说一句,您可以告诉我,我很乐意为您提供帮助。

以上是关于JUnit 和 Surefire 并行测试 - ForkCount 和 ThreadCount的主要内容,如果未能解决你的问题,请参考以下文章

Junit 并行执行测试

并行执行没有发生在Cucumber JVM 4.0.0和Junit测试运行器上

如何让 maven surefire 正确执行 JUnit 和 TestNG 测试?

使用 maven-surefire-plugin 进行 JUnit 和 Spock 测试

maven-surefire 插件没有运行少数 Junit5 测试配置文件

如何使用 maven-surefire-plugin 在同一个项目中执行 JUnit 和 TestNG 测试?