我们的部门创建全自动管道,用于将新版本的应用程序启动到生产环境中。 当然,这需要自动化的功能测试。 下面是一个故事,讲述我们如何从本地机器上的单线程测试开始,通过 GitLab 页面上的 Allure 报告,达到在构建管道中的 Selenoid 上运行多线程自动测试的阶段,并最终获得一个很酷的自动化工具未来的人们可以使用团队。
我们从哪里开始?
为了实现自动测试并将其集成到管道中,我们需要一个可以灵活更改以满足我们的需求的自动化框架。 理想情况下,我希望为自动测试引擎制定一个单一标准,适合将自动测试嵌入到管道中。 为了实现,我们选择了以下技术:
- Java
- 专家,
- 硒,
- 黄瓜+JUNIT 4,
- 引诱,
- 亚搏体育app。
为什么是这个特定的集合? Java 是自动化测试最流行的语言之一,所有团队成员都会使用它。 硒是显而易见的解决方案。 除其他外,Cucumber 应该可以提高参与手动测试的部门对自动化测试结果的信心。
单线程测试
为了不重新发明轮子,我们将 GitHub 上各个存储库的开发成果作为框架的基础,并为我们自己进行了调整。 我们为主库创建了一个存储库,其中包含自动测试框架的核心,以及一个存储库,其中包含在我们的核心上实现自动测试的黄金示例。 每个团队都必须获取黄金镜像并在其中开发测试,使其适应他们的项目。 我们将其部署到 GitLab-CI 银行,并在其上配置:
- 每个项目的所有书面自动测试的每日运行;
- 在构建管道中启动。
一开始测试很少,而且是在一个流程中进行的。 在 Windows 运行器 GitLab 上运行的单线程非常适合我们:测试对测试平台的加载非常轻,几乎不使用任何资源。
随着时间的推移,自动测试的数量变得越来越多,当完整运行开始需要大约三个小时时,我们考虑并行运行它们。 还出现了其他问题:
- 我们无法验证测试是否稳定;
- 在本地计算机上连续运行多次的测试有时会在 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 分叉测试
由于我们在实现基本框架时没有考虑线程安全代码,因此并行运行的最明显的方法是
Selenoid 服务器在具有 32 个内核和 24 GB RAM 的机器上启动。 限制设置为 48 个浏览器 - 每个核心 1,5 个线程和大约 400 MB 的 RAM。 结果,测试时间从 40 小时减少到 20 分钟。 加快运行速度有助于解决稳定性问题:现在我们可以快速运行新的自动测试 30-XNUMX 次,直到我们确定它们运行可靠。
该解决方案的第一个缺点是并行线程数量较少,运行程序资源利用率较高:在 4 核和 8 GB RAM 上,测试在不超过 6 个线程中稳定运行。 第二个缺点:插件会为每个场景生成运行器类,无论启动了多少个。
重要的信息! 不要将带有标签的变量传递给 参数线,例如,像这样:
<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>**/*IT.class</includes>
<testFailureIgnore>false</testFailureIgnore>
<!--suppress UnresolvedMavenProperty -->
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" -Dcucumber.options="--plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm TagPFAllureReporter --plugin pretty"
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
Allure 报告示例(最不稳定的测试,重新运行 4 次)
测试期间的运行器负载(8 核、8 GB RAM、12 线程)
优点:
- 简单设置 - 您只需要添加一个插件;
- 同时执行大量测试的能力;
- 由于步骤 1,加速了测试稳定性。
缺点:
- 需要多个操作系统/容器;
- 每个分叉资源消耗高;
- 该插件已过时,不再受支持。
如何克服不稳定因素
测试台并不理想,就像自动测试本身一样。 我们有许多不稳定的测试并不奇怪。 前来救援
设置自动测试的示例:
<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>
Allure 报告示例(最不稳定的测试,重新运行 5 次)
测试期间的运行器负载(8 核、8 GB RAM、24 线程)
优点:
- 资源消耗低;
- Cucumber 的本机支持 - 无需额外工具;
- 每个处理器核心运行 6 个以上线程的能力。
缺点:
- 您需要确保代码支持多线程执行;
- 进入门槛提高。
GitLab 页面上的 Allure 报告
引入多线程执行后,我们开始花更多时间分析报告。 当时,我们必须将每个报告作为工件上传到 GitLab,然后下载并解压。 不是很方便,而且需要很长时间。 如果其他人想亲自查看报告,那么他们将需要执行相同的操作。 我们希望更快地收到反馈,我们找到了一个解决方案 - GitLab 页面。 这是一个内置功能,在所有最新版本的 GitLab 中都可以开箱即用。 允许您在服务器上部署静态站点并通过直接链接访问它们。
Allure 报告的所有屏幕截图均在 GitLab 页面上截取。 用于将报告部署到 GitLab 页面的脚本 - 在 Windows PowerShell 中(在此之前您需要运行自动测试):
New-Item -ItemType directory -Path $testresulthistory | 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 $buildlocationtargetsiteallure-maven-plugin* $buildlocationpublic /s /i /Y
其结果是
因此,如果您正在考虑 Cucumber 自动测试框架中是否需要线程安全代码,那么现在答案很明显 - 使用 Cucumber 4 可以轻松实现它,从而显着增加同时启动的线程数量。 通过这种运行测试的方法,现在的问题就变成了带有 Selenoid 的机器和测试台的性能。
实践表明,在线程上运行自动测试可以让您将资源消耗降至最低,同时获得最佳性能。 从图中可以看出,加倍线程并不会导致性能测试中类似的加速。 然而,我们能够向应用程序构建添加 2 多个自动化测试,即使重新运行 200 次,运行时间也约为 5 分钟。 这使您可以从他们那里收到快速反馈,并在必要时进行更改并再次重复该过程。
来源: habr.com