无需启动100个应用程序-只需进行一次自动测试,或如何挽救质量检查工程师20年的生命

大家好,我叫Evgeny Demidenko。在过去的几年中,我一直在Pixonic开发自动游戏测试系统。今天,我想分享我们在《战争机器人》项目中开发,支持和使用这种系统的经验。

首先,我们将弄清楚我们正在使用该系统进行的自动化操作。

首先,这些是回归UI测试,核心游戏性测试和基准测试自动化。这三个系统作为一个整体,可以减少发布前质量检查部门的负担,对大规模和深度重构更有信心,并始终保持对应用程序及其各个部分性能的总体评估。我想指出的另一点是例程的自动化,例如-检验所有假设。

图片

我会给出一些数字。现在,已为War Robots编写了600多个UI测试和大约100个核心测试。仅在这个项目上,我们就发布了大约一百万个测试脚本,每个脚本耗时约80秒。如果我们手动检查这些方案,则每个方案至少要花费五分钟。此外,我们推出了70万多个基准。

在这些平台中,我们使用Android和iOS-公园中只有12台设备。两名程序员参与了系统开发和支持,一名QA工程师正在编写和分析测试。






对于软件堆栈,我们在数据库中使用NUnit,但不是用于单元测试,而是用于集成和系统测试。对于核心游戏玩法和构建验证测试,我们使用Unity的内置解决方案-Unity Test Tools。为了在这些测试之后编写和分析报告,使用了Yandex的Allure Test Report以及TeamCity-作为应用程序构建,服务器部署和运行测试的持续集成系统。我们使用Nexus Repository和PostgreSQL数据库来存储我们的工件。




您如何创建,分析和运行测试


假设我们要编写一个简单的测试,在游戏设置窗口中将检查用于打开和关闭声音的图标。

因此,我们编写了一个测试并将其提交到测试存储库中的特定分支。我们选择了要运行的测试,选择了要运行的构建,或者选择了要在其上组装构建的特定提交。现在运行测试,稍等片刻即可得到结果。





在这种情况下,启动了575个测试,其中97%成功。我们花了大约三个小时才能完成所有测试。为了进行比较,如果手动进行相同的测试,则至少需要连续运行50小时。

那么,失败的那3%的测试怎么了?

我们打开一个特定的测试,并看到一条消息,指出在匹配屏幕截图时发生了错误。



然后,我们打开屏幕快照,该屏幕快照当时在设备上,并且我们看到与原始图像不对应的区域标记有红色像素。为了比较,我们给他。





自然地,此后,QA工程师必须犯一个错误,即构建的行为与游戏设计文档不符,或者更新原始屏幕截图,因为游戏设计文档已更改,现在这些元素将不在游戏中。


看起来很酷。为什么这一切都是必要的?


前一段时间,在《战争机器人》项目中,我们需要进行一次小型重构。它包括重写一些用于发射武器(尤其是机枪)的代码。

在测试过程中,我们发现了一个有趣的细微差别:机关枪的速度直接取决于FPS。在手动测试期间检测到这样的错误是不现实的:首先,由于网络计算了项目损坏的特征,其次,由于War Robots应用程序经过了很好的优化,并且当时可以在所有操作系统上运行FPS大致相同的设备-30帧/秒。当然,偏差很小,但不足以引起手动测试过程中发射武器的伤害增加。然后我们问自己:我们仍然有多少个此类错误,在重构期间会出现多少个错误?

由于我们不想减少测试数量,而是希望增加测试数量,因为我们计划进行重大更新并增加内容数量,所以我们不想横向增长并增加质量检查部门员工的数量。相反,我们计划垂直增长,以减少现有员工的日常工作,并在对新内容进行集成测试期间简化他们的生活。




我们使用什么工具


刚开始自动化测试时,我们首先要注意Unity集成测试工具,该工具当时是在Unity中内置的。我们为此编写了多个UI和核心测试,完成了我们较早开始的重构,并对它感到满意,因为该解决方案已经有效,这意味着我们的假设是正确的,我们必须继续前进。该解决方案的唯一缺点是对测试不能在移动设备上运行,但对我们而言非常重要。

因此,我们提出了使用Appium框架的想法。这是另一个著名的测试框架-Selenium的分支。反过来,它也许是测试Web应用程序最著名的框架,其主要概念是使用UI元素,获取它们的坐标并将输入组织到这些UI元素中。 Appium采纳了这一概念,除了Selenium中现有的Web驱动程序之外,还添加了iOS和Android驱动程序:它们对每个平台都使用本机测试框架。

由于Unity中没有本机UI元素,并且只有一个UI元素可在其中渲染图片,因此除了Appium UnityDriver之外,我还需要添加其他东西,它允许您使用场景层次结构,获取场景对象等。

那时,QA工程师已经出现在项目中,事情开始流行,测试方案的数量开始显着增长,而我们逐渐将其自动化。我们开始在设备上启动它们,总的来说,我们的工作已经在寻找我们想要的方式。

将来,除了UI测试之外,更多的基于我们系统的核心测试和其他工具开始出现,结果我们遇到了各种设备的性能和工作质量,增加了对更多设备的支持,并行测试,并且放弃了Appium您自己的框架的好处。



UI层次结构一直是我们面临的唯一问题,现在仍然是。因为如果由于UI重构或在场景上工作而导致场景中的层次结构发生更改,则需要在测试中对此进行支持。

经过下一次的创新和修订,整个系统的体系结构开始看起来如下。



我们使用War Robots构建,并在单独的存储库中进行测试,添加一些要在其中运行的参数,这些参数使我们可以配置每种情况下的测试启动,并将其全部发送到远程PC上的TeamCity代理。 TeamCity代理启动我们的测试,向他们传递Robot的构建和启动参数,然后测试开始工作,并与通过有线方式连接到TeamCity代理的设备独立“通信”:在其上构建,运行它们,执行某些脚本,删除构建,重新启动应用程序等。

由于测试和应用程序本身在物理上不同的设备上(在手机和Mac mini上)运行,因此我们需要在框架,War Robots API和Unity API之间实现通信。我们在应用程序中添加了一个小型UDP服务器,该服务器从框架接收命令,并通过处理程序与应用程序API和Unity通信。



我们框架的主要任务是组织测试工作:正确准备,完成和管理设备。特别是并行化可以加快工作速度,正确选择设备和屏幕截图,以及与版本进行通信。完成测试后,我们的框架应保存所有生成的工件并生成报告。


选择设备的提示


另外,我要注意测试设备的选择。

应该特别注意集线器。如果您想在设备上运行基准测试(尤其是在Android设备上),则它们将耗尽电源。集线器必须为使用的设备提供必要的电源。还有一个非常微妙的功能:一些集线器具有有功电源,并且在电涌后此电源会关闭,然后仅通过物理按下按钮才能将其打开。我们有这样的中心,这非常不方便。

如果要在设备上运行回归UI测试和测试逻辑,请不要使用其他设备。使用相同的设备-最好用最实惠的设备,因为这样可以节省设备制动器的时间,使用它们的便利性以及所有设备上应用程序的行为都相同。

一个单独的问题是云服务器场的使用。尽管我们已经对它们进行了研究:它们是什么,它们的成本和如何对它们进行测试,但我们还没有使用它们-但是到目前为止,我们有足够的内部设备园区来满足我们的要求。


测试报告


测试完成后,我们将生成一个诱人的报告,其中包括在测试期间创建的所有工件。

日志是用于分析发生的情况并确定测试过程中崩溃原因的主要“主力军”。首先,我们从框架中收集它们,从而告诉我们脚本的状态以及此脚本中发生了什么。我们将日志分为系统(更详细)和质量检查日志(更紧凑且便于分析)。我们还从设备(例如logcat)收集系统日志,并从Unity应用程序收集日志。

在测试的秋天期间,我们还拍摄了一张屏幕截图,以了解坠落时设备上发生的情况,录制视频以了解崩溃前发生的事情,并尝试最大程度地收集有关设备状态的信息,例如服务器ping和ifconfig信息了解设备是否具有IP。但是,如果您手动启动该应用程序50次,一切都会很好,但是如果您以自动模式运行该应用程序5万次,您会发现设备上的Internet可能丢失,并且在测试过程中不清楚,这会让您感到惊讶。跌倒前后是否有联系。

我们还会收集过程,电池电量,温度以及我们可以到达的所有内容的列表。




什么是好的截图和视频


不久前,我们的质量检查工程师建议,除了在秋季拍摄屏幕快照外,还建议在测试中的某些地方将这些屏幕快照与我们存储库中的模板进行比较。因此,他建议节省测试运行时间并减少代码库的大小。也就是说,通过一项测试,我们可以检查逻辑和可视部分。从单元测试的概念的角度来看,这不是很正确,因为在一次测试中,我们不应测试多个假设。但这是一个刻意的步骤:我们知道如何正确分析所有这些内容,因此我们冒险添加类似的功能。

首先,我们考虑添加库以匹配屏幕截图,但是我们意识到使用分辨率不同的图像并不是很可靠,因此我们在分辨率相同的设备上停止了工作,只是将图像与特定阈值逐像素进行比较。



使用屏幕截图匹配的一个非常有趣的效果是,如果某些过程难以实现自动化,我们将尽可能地自动化它,然后我们只需手动查看屏幕截图即可。这正是我们对测试本地化所做的。我们收到了测试应用程序本地化的请求,因此我们开始研究允许文本识别的库-但我们意识到这种方法不可靠,因此我们编写了多个脚本,这些脚本在不同的屏幕上“遍历”并导致不同的弹出窗口。 ups,此时将创建屏幕截图。在启动这样的脚本之前,我们更改设备上的语言环境,运行脚本,截屏,再次更改语言环境,然后再次运行脚本。因此,所有测试都在晚上进行,因此,质量检查工程师可以在早上查看500张屏幕截图,并立即分析某处的本地化是否存在问题。是的,仍然需要观看屏幕截图,但这比手动浏览设备上的所有屏幕要快得多。

有时屏幕截图和日志还不够:设备上开始发生奇怪的事情,但是由于它们位于远程,因此您无法去评估那里发生的事情。而且,有时不清楚在测试失败前片刻发生了什么。因此,我们从设备添加了一个视频记录,该记录从测试开始就开始,并且仅在跌倒时才保存。借助此类视频,跟踪应用程序崩溃和冻结非常方便。




我们的系统还能做什么?


不久前,我们从质量检查测试部门收到了一项要求,要求开发一种用于在手动游戏测试期间收集指标的工具。

这是为了什么

这是必要的,以便QA工程师在进行手动游戏测试后,可以另外分析FPS的行为和应用程序中的内存消耗,同时查看反映该设备上发生的情况的屏幕截图和视频。

我们开发的系统工作如下。质量检查工程师在设备上启动了War Robots,打开了Playbench会话(我们的游戏平台类似物)的记录,进行了游戏测试,然后单击“结束Playbench会话”,将生成的报告保存在存储库中,之后工程师可以使用此Playtest的数据进行工作机器,然后查看报告:FPS的耗资是多少,内存消耗是多少,设备上正在发生什么。

我们还对《战争机器人》项目的基准测试的发布进行了自动化,实际上只是将现有的基准测试包装在自动启动中。基准测试的结果通常为一位数。在我们的案例中,这通常是每个基准的平均FPS。除了自动启动之外,我们决定添加另一个playbench会话,因此不仅收到一个特定的数字,基准的工作原理,还收到了一些信息,通过这些信息,我们可以分析当时基准的情况。

我们还应该提到拉取请求测试。这次更多的是帮助客户开发团队,而不是质量检查工程师。我们为每个拉取请求运行所谓的构建验证测试。您可以在设备上和Unity编辑器中运行它们,以加快逻辑检查的速度。我们还在单独的分支中运行一组核心测试,在这些分支中,对某些元素进行了某种重新设计或对代码进行重构。




和其他有用的功能


最后,我想谈谈过去几年我们遇到的一些有趣的案例。

最近与我们一起出现的最有趣的案例之一是与机器人打架时的基准测试。

对于新项目,Pixonic Dino Squad开发了一个系统,质量检查工程师可以在该系统中使用机器人进行游戏测试,以免等待同事,而是测试某些假设。反过来,我们的质量检查工程师要求增加不仅可以与机器人玩耍的功能,而且还可以使机器人彼此玩耍。因此,我们只需启动该应用程序,此刻该bot就开始与其他bot一起玩。同时,所有交互都是通过网络与真实的服务器进行的,而不仅仅是玩家玩计算机。所有这些都包含在基准测试和带有夜间启动触发器的Playbench会话中。因此,在晚上,我们开始在僵尸程序和僵尸程序之间进行几场战斗,这时将编写FPS和内存消耗,拍摄屏幕截图并录制视频。早上,质量检查工程师来了,可以看到,举行了哪些游戏测试以及发生了什么。

还值得检查的是纹理泄漏。这是对内存使用情况的一种子分析-但是在这里,我们主要检查例如战斗中车库纹理的使用情况。因此,在战斗中,不应在车库中使用地图集,并且当我们退出战斗时,在战斗中使用的纹理不应保留在内存中。

我们系统的一个有趣的副作用是,几乎从其使用之初就一直跟踪应用程序的加载时间。就War Robots而言,这段时间并不长,但它会不断增长,因为正在添加新内容,并且该内容的质量也在提高-但是我们可以控制此参数并始终知道其大小。


而不是结论


最后,我想提请大家注意我们首先要解决的问题。



第一个也是最痛苦的是UI更改。由于我们使用的是黑匣子,因此除了服务器以外,我们没有在War Robots应用程序中嵌入任何内容-也就是说,我们以与质量检查工程师测试相同的方式来测试所有内容。但是我们需要以某种方式访问​​场景中的元素。我们沿着绝对路径找到它们。因此,当阶段中发生某些变化时,尤其是在较高层次结构上,我们必须在大量测试中支持这些变化。不幸的是,我们现在无法对此做任何事情。当然,有一些解决方案,但是它们带来了其他问题。

第二大问题是基础设施。就像我说的那样,如果您的应用程序运行了50次,那么您不会注意到大多数问题(如果运行5万次)。那些在手动模式下可以轻松解决的问题-例如,重新安装内部版本或重新启动Internet-最终将成为自动化领域的真正痛苦,因为必须正确处理所有这些问题,并显示一条错误消息,并假设它们可以发生。特别是,我们需要确定测试失败的原因:由于逻辑故障或某种基础架构问题,或任何其他原因。低端设备存在很多问题:它们没有构建,Internet掉线,设备冻结,崩溃,无法开机,被快速放电等。

我也想与本机UI进行交互,但是到目前为止,我们还没有这样的机会。我们知道如何执行此操作,但是由于存在其他功能要求,因此我们无法做到这一点。

就个人而言,我的愿望是遵守行业中存在的标准,但这也是将来甚至今年的计划。

All Articles