我们的部门创建了全自动管道,用于将新版本的应用程序输出到生产环境。 当然,这需要自动化的功能测试。 切入的故事-如何从在本地计算机上的一个线程中进行测试开始,到GitLab页面上的Allure报告,在装配管线中以Selenoid进行多线程自检,结果我们得到了一个很酷的自动化工具,以后的人可以使用团队。

我们从哪里开始
为了实现自动测试并将其集成到管道中,我们需要一个自动化框架,可以对其进行灵活更改以适应我们的需求。 理想情况下,我想为自动测试引擎获得一个单一标准,该标准适用于将自动测试嵌入到管道中。 为了实现,我们选择了以下技术:
- 爪哇
- 马文
- 硒类
- 黄瓜+ JUNIT 4,
- 魅力
- Gitlab

为什么要这样一套? Java是最流行的自动测试语言之一,此外,团队中的所有成员都在使用Java。 硒是显而易见的解决方案。 除其他外,黄瓜被认为可以提高参与手动测试的单位对自动测试结果的信心。
单线程测试
为了不浪费时间,我们将GitHub上各个存储库的开发成果作为框架的基础,并对其进行了调整。 我们使用自动测试框架的核心为主库创建了一个存储库,并使用在我们的核心上实现自动测试的Gold示例创建了一个存储库。 每个团队都必须拍摄金色图像并在其中进行测试,以使其适应他们的项目。 我们部署到了GitLab-CI银行,并在其上进行了配置:
- 每个项目的所有书面自动测试的日常运行;
- 在组装管道中启动。
最初,很少有测试,它们合而为一。 在GitLab Windows运行程序上的单线程启动对我们来说是令人满意的:测试仅轻微地加载了测试台,并且几乎没有利用资源。
随着时间的流逝,自动测试变得越来越多,我们开始考虑并行运行它们,而完整的测试大约需要三个小时。 还有其他问题:
- 我们无法确定测试是否稳定;
- 在本地计算机上连续运行几次的测试有时会落入CI。
自动测试设置示例:
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.20</version> <configuration> <skipTests>${skipTests}</skipTests> <testFailureIgnore>false</testFailureIgnore> <argLine> -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" -Dcucumber.options="--tags ${TAGS} --plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm --plugin pretty" </argLine> </configuration> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectj.version}</version> </dependency> </dependencies> </plugin> <plugin> <groupId>io.qameta.allure</groupId> <artifactId>allure-maven</artifactId> <version>2.9</version> </plugin> </plugins>
魅力报告示例
测试期间的流道负载(8核,8 GB RAM,1个线程)单线程测试的优点:
- 易于配置和运行;
- 实际上,CI中的发布与本地发布没有什么不同;
- 测试不会相互影响;
- 最低跑步者资源要求。
单线程测试的缺点:
- 很长的时间
- 长期稳定的测试;
- 流道资源利用效率低下,利用率极低。
JVM前叉测试
由于在实现基本框架时我们并不关心线程安全代码,因此Maven的
Cucumber-jvm-parallel-plugin成为最明显的并行运行方式。 该插件易于配置,但是要正确执行自动测试的并行操作,您需要在单独的浏览器中运行。 什么也没做,我不得不使用硒油。
Selenoid服务器在具有32个内核和24 GB RAM的计算机上运行。 该限制是在48个浏览器中设置的-每个内核1.5个线程和大约400 MB的RAM。 结果,测试时间从三小时减少到40分钟。 加快运行速度有助于解决稳定性问题:现在,我们可以快速运行20-30次新的自动测试,直到我们确保它们执行稳定为止。
该解决方案的第一个缺点是运行资源的利用率高,并行线程数量少:在4个内核和8 GB RAM上,测试在不超过6个线程中稳定运行。 第二个缺点:无论运行多少,该插件都会为每种情况生成运行程序类。
重要! 例如,不要在
argLine中使用标签抛出变量,例如:
<argLine>-Dcucumber.options="--tags ${TAGS} --plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm --plugin pretty"</argLine> … Mvn –DTAGS="@smoke"
如果以这种方式传递标签,则插件将为所有测试生成运行程序,即尝试运行所有测试,在启动后立即跳过它们,并创建大量JVM分支。
将带有标签的变量放入插件设置的
标签中是正确的,请参见下面的示例。 我们测试的其他方法在连接Allure插件时遇到问题。
错误设置的6个简短测试的示例运行时间:
[INFO] Total time: 03:17 min
如果直接将标签传递给
mvn ... –Dcucumber.options,则为测试运行时的
示例 :
[INFO] Total time: 44.467 s
自动测试设置示例:
<profiles> <profile> <id>parallel</id> <build> <plugins> <plugin> <groupId>com.github.temyers</groupId> <artifactId>cucumber-jvm-parallel-plugin</artifactId> <version>5.0.0</version> <executions> <execution> <id>generateRunners</id> <phase>generate-test-sources</phase> <goals> <goal>generateRunners</goal> </goals> <configuration> <tags> <tag>${TAGS}</tag> </tags> <glue> <package>stepdefs</package> </glue> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.21.0</version> <configuration> <forkCount>12</forkCount> <reuseForks>false</reuseForks> <includes>**
魅力报告的示例(最不稳定的测试,4次再呼吸)
测试期间的流道负载(8核,8 GB RAM,12个线程)优点:
- 简单的设置-您只需要添加插件;
- 同时执行大量测试的能力;
- 借助权利要求1,可以更快地稳定测试。
缺点:
- 需要多个操作系统/容器;
- 每叉的资源消耗很高;
- 该插件已弃用,不再受支持。
如何克服不稳定
测试台和自动测试本身都不是完美的。 毫不奇怪,我们进行了许多测试。
Maven surefire插件可以提供帮助,该
插件开箱即用,支持重新启动已删除的测试。 您需要将插件版本至少更新为2.21,并在pom文件中写上一行带有重新启动次数的代码,或者将其作为Maven的参数传递。
自动测试设置示例:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.21.0</version> <configuration> …. <rerunFailingTestsCount>2</rerunFailingTestsCount> …. </configuration> </plugin>
或在启动时:
mvn ... -Dsurefire.rerunFailingTestsCount = 2 ...或者,为PowerShell脚本(PS1)设置Maven选项:
Set-Item Env:MAVEN_OPTS "-Dfile.encoding=UTF-8 -Dsurefire.rerunFailingTestsCount=2"
优点:
- 当不稳定的测试崩溃时,无需浪费时间分析它;
- 您可以消除测试台的稳定性问题。
缺点:
使用Cucumber 4库进行并行测试
测试的数量每天都在增加。 我们再次考虑加快运行速度。 另外,我想将尽可能多的测试集成到应用程序的管道程序集中。 一个关键因素是使用Maven插件并行运行时赛跑者生成的时间太长。
那时Cucumber 4已经发布了,所以我们决定为该版本重写内核。 在发行说明中,我们承诺在线程级别并行启动。 从理论上讲,这应该是:
- 通过增加线程数,大大加快了自动测试的运行速度;
- 排除每次自动测试产生跑步者的时间损失。
为多线程自动测试优化框架并不是那么困难。 Cucumber 4从头到尾在专用线程中运行每个单独的测试,因此一些常见的静态操作仅被转换为ThreadLocal变量。
使用Idea重构工具进行转换时,主要的工作是检查比较变量的位置(例如,检查null)。 此外,您需要在Junit Runner类的注释中呈现Allure插件。
自动测试设置示例:
<profile> <id>parallel</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M3</version> <configuration> <useFile>false</useFile> <testFailureIgnore>false</testFailureIgnore> <parallel>methods</parallel> <threadCount>6</threadCount> <perCoreThreadCount>true</perCoreThreadCount> <argLine> -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" </argLine> </configuration> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectj.version}</version> </dependency> </dependencies> </plugin> </plugins> </build> </profile>
魅力报告的示例(最不稳定的测试,5次重试)
测试期间的流道负载(8核,8 GB RAM,24个线程)优点:
- 资源消耗低;
- Cucumber的本地支持-无需其他工具;
- 能够在处理器内核上运行6个以上线程。
缺点:
GitLab页面中的魅力报告
引入多线程启动后,我们开始花更多的时间来分析报告。 当时,我们必须将每个报告作为工件上传到GitLab,然后下载并解压缩。 它不是很方便而且很长。 如果其他人想在家中查看报告,那么他将需要执行相同的操作。 我们希望更快地获得反馈,并且有一种解决方法-GitLab页面。 这是一项内置功能,在所有最新版本的GitLab中均可使用。 允许您在服务器上部署静态站点并通过直接链接访问它们。
所有带有“魅力”报告的屏幕截图均在GitLab页面中制作。 将报告部署到GitLab页面的脚本是Windows PowerShell(在您需要运行自动测试之前):
New-Item -ItemType directory -Path $testresult\history | Out-Null try {Invoke-WebRequest -Uri $hst -OutFile $outputhst} Catch{echo "fail copy history"} try {Invoke-WebRequest -Uri $hsttrend -OutFile $outputhsttrnd} Catch{echo "fail copy history trend"} mvn allure:report #mvn assembly:single -PzipAllureReport xcopy $buildlocation\target\site\allure-maven-plugin\* $buildlocation\public /s /i /Y
结果如何
因此,如果您考虑在Cucumber自动测试框架中是否需要线程安全代码,那么答案很明显-使用Cucumber 4可以轻松实现它,从而显着增加了同时启动的线程数。 通过这种运行测试的方法,问题已经在关于带有硒油样和测试台的机器的性能。
实践表明,在线程上运行自动测试可以以最佳性能最大程度地减少资源消耗。 从图中可以看出,流量的2倍增长不会导致通过性能测试时出现类似的加速。 尽管如此,我们仍然能够在应用程序组装中添加200多个自动测试,即使进行5次重试也可以在大约24分钟内完成。 这样您可以从他们那里收到快速反馈,并且,如有必要,进行更改并再次重复该过程。