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+ 并在配置中使用并行运行测试的配置太多了。
根据文档:
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的主要内容,如果未能解决你的问题,请参考以下文章
并行执行没有发生在Cucumber JVM 4.0.0和Junit测试运行器上
如何让 maven surefire 正确执行 JUnit 和 TestNG 测试?
使用 maven-surefire-plugin 进行 JUnit 和 Spock 测试