在Odnoklassniki扩展Android测试



你好!我的名字叫Roman Ivanitsky,我在Odnoklassniki测试自动化团队中工作。 OK是一项庞大的服务,拥有超过7000万用户。如果我们谈论移动设备,则大多数人在运行Android的智能手机上使用OK.RU。因此,我们非常认真地测试我们的Android应用程序。在本文中,我将讲述我们公司自动测试开发的故事。

2012年,Odnoklassniki公司正经历着用户数量的积极增长和用户功能数量的增长。为了满足业务目标,必须缩短发布周期,但是由于所有功能都是手动测试的事实而受到阻碍。解决此问题的方法本身就是-我们需要自动测试。因此,2012年在Odnoklassniki出现了一个测试自动化团队,第一步是开始编写测试。

一点历史


Odnoklassniki中的第一个自动测试是用Selenium编写的,它们的发布引发了Jenkins,带有Selenium Hub的Selenium Grid和一组Selenium Node的出现。

快速解决方案,快速启动,快速获利-完美。

随着时间的流逝,测试的数量增加了,并且出现了辅助服务-例如,启动服务,报告服务,测试数据服务。到2014年底,我们进行了大约十五到二十分钟的一千次测试。这显然不适合我们,因为很明显,测试数量会增加,运行测试所需的时间也会增加。

当时,自动化测试基础架构如下所示:



但是,如果硒节点的数量大于或等于200,则集线器将无法应付负载。现在已经研究了这个问题,这就是为什么出现诸如Zalenium或每个人都喜欢的Selenoid之类的工具的原因。但是在2014年,尚无标准解决方案,因此我们决定自己制造。

定义了服务必须满足的最低要求:

  1. 可扩展性。我们不想依赖Selenium Hub的限制。
  2. 稳定性。2014年,Selenium Hub以稳定的运行而闻名。
  3. 容错能力。如果数据中心或任何服务器出现故障,我们需要有继续测试过程的能力。

因此,出现了我们的Selenium Grid缩放解决方案,它由一个协调器和Node-manager组成,在外观上与标准Selenium Grid非常相似,但是具有自己的功能。这些功能将进一步讨论。

协调员




实际上,它是一个资源代理(资源被理解为浏览器)。它具有外部API,测试可通过该API发送对资源的请求。这些查询将作为要运行的任务保存到数据库中。协调员了解有关集群配置的所有信息-存在哪些节点管理器,这些节点管理器可以提供哪些资源,资源总数,当前任务中涉及多少资源。同时,他监视资源-活动,稳定性,并在这种情况下通知责任人。

协调器的一个功能是将所有Node Manager集成到所谓的服务器场中。

这就是农场的样子。使用了一半以上的资源,并且所有节点均处于联机状态:



您还可以脱机显示节点或将其旋转一定百分比,如果有必要减少特定节点上的负载,则需要这样做。

每个服务器场都可以在逻辑单元(我们称为服务)中与其他服务器场组合。同时,一个农场可以包含在几种不同的服务中。首先,它可以设置限制并确定每个特定服务使用的资源的优先级。其次,它使您可以轻松地管理配置-我们能够即时添加服务中节点管理器的数量,反之亦然,可以从服务器场中删除它们以与这些节点管理器进行交互,例如配置或更新等。 。



协调器的API非常简单:可以针对当前使用的资源量请求服务,获取其限制并启动或停止某些资源。

节点管理器


这是一项可以很好地完成两件事的服务-从协调员那里接收任务,并根据需要启动一些资源。默认情况下,它的设计使资源的每次启动都是隔离的,也就是说,以前的启动都不会影响后续测试的启动。作为响应,协调器使用了一堆主机和一组升高的端口。例如,启动Selenium服务器的主机及其端口。



在主机上,它看起来像这样:节点管理器服务正在运行,并且它管理整个资源生命周期。他选择了浏览器,完成了浏览器,确保不会忘记关闭它们。为了确保彼此隔离,所有这些都代表服务用户进行。

相互作用


该测试与上述基础结构进行如下交互:它向协调器发出对必需资源的请求,协调器将此任务保存为需要执行。

依次,节点管理器求助于任务协调器。收到任务后,他启动了资源。之后,他将启动结果发送给协调器,失败的启动也将报告给协调器。测试会收到资源请求的结果,如果成功,则直接开始使用资源。



这种方法的优点是通过获得直接使用资源的能力来减少协调器上的负载。缺点-需要在测试框架内实现与协调器交互的逻辑,但是对我们来说这是可以接受的。
今天,我们可以在三个数据中心并行运行800多个浏览器。对于协调员,这不是限制。

通过启动缠绕在不同数据中心的DNS防火墙后面的多个协调器实例,可以确保容错能力。如果数据中心或服务器出现问题,这可以保证对工作实例的访问。

结果,我们得到了一个满足所有初始设置要求的解决方案。自2015年以来一直稳定运行,并证明了其有效性。

安卓系统


在Android上进行测试时,通常有两种主要方法。首先是使用WebDriver-这是Selendroid和Appium的工作方式。第二个-使用本地工具,从而实现了Robotium,UI Automator或Espresso。

这些方法之间的基本相似之处是获得设备并获得浏览器。

还有更多区别,主要是需要安装经过测试的APK,我们将通过日志,屏幕截图等形式获取工件。而且,测试是在设备本身而不是在CI上进行的。

在2015年,Odnoklassniki开始使用自动测试覆盖其Android应用程序。我们选择了一台Linux机器,通过USB连接一台真实设备,然后开始在Robotium上编写测试。这个简单的解决方案使您可以快速获得结果。

时间过去了,测试数量和设备数量都在增加。为了解决管理任务,创建了设备管理器-覆盖adb(Android调试桥)命令的包装程序,该命令允许http api接口执行它们。

这就是设备管理器的第一个API的外观-借助它的帮助,您可以获得设备列表,安装/卸载APK,运行测试并获得结果。



但是,我们注意到,在连接了多个设备的ADB服务器上启动时,测试结果会降低。在使用Docker隔离每台ADB服务器的过程中发现了有助于提高稳定性的解决方案。

场已准备就绪-您可以连接电话。



许多人都熟悉这张照片。听说如果您从事Android农场,那么您每天都会陷入困境。



我们提供了一个Android模拟器。它的使用归因于两个因素:首先,当时它已经达到了必要的稳定性水平;其次,我们在测试中没有任何特别依赖铁的功能。此外,当时该模拟器已很好地投影到现有基础架构上。下一步是教节点管理器启动新型资源。

运行Android模拟器需要什么?

首先,您需要一个带有一组实用程序的Android SDK。

然后,您需要创建AVD-Android虚拟设备-这是您的Android仿真器的组织方式-它具有什么架构,将使用多少个内核,是否可以使用Google服务,等等。



之后,您需要选择创建的AVD的名称,设置参数,例如,转移将启动ADB的端口,然后启动。

但是,这种方案有一个特殊性-系统仅允许您在一个特定的AVD上运行一个实例仿真器。

解决此问题的方法是创建一个存储在内存中的基本AVD,从而可以将其复制到其他位置。在启动Android模拟器期间,基本AVD被复制到映射到内存的临时目录中,然后启动。这样的方案工作很快,但是很麻烦。迄今为止,该问题已通过只读选项解决,该选项使您可以从一个AVD无限数量地运行Android仿真器

性能


根据与AVD合作的结果,我们提出了一些内部建议:

  1. 86 , ARM . dev/kvm Linux HAXM- Mac Windows
  2. GPU- . , . , , , Android-
  3. .
  4. , localhost,

至于要在Android上进行测试的Docker映像,我想强调一下Agoda和Selenoid,他们最大程度地利用了Android仿真器的功能。

它们之间的区别在于默认的Selenoid中有Appium,Agoda和使用过的“干净”模拟器。此外,Selenoid具有更多的社区支持。

在2018年底,创建了CloudNode-Manager,它与协调器联系,接收任务并使用云中的命令启动。该服务代替铁机使用了一个云的资源-Odnoklassniki自己的私有云。

我们设法通过教DeviceManager如何与协调器一起工作来实现扩展。为此,我必须更改设备管理器API以添加请求设备类型(虚拟/真实)的功能。

如果您尝试在一台计算机上的250个仿真器上运行ADB安装,则会发生这种情况。



服务员立即对此做出了反应并引发了事件-机器向千兆位网络接口加载了传出流量。通过增加服务器的吞吐量解决了这种复杂性。我不能说这个问题给我们带来了很多麻烦,但您不要忘记它。

看来成功是Devicemanager,协调器,扩展。我们可以在整个服务器场上运行测试。原则上,我们可以在每个请求请求上运行它们,开发人员将很快收到反馈。



但是,并非所有事情都如此乐观。您可能已经注意到,到目前为止,关于测试质量还没有任何评论。



这就是我们的发布会的样子。最有趣的是,在两次发射之间可能会落入完全不同的测试。这些是不稳定的瀑布。我,开发人员和测试人员都不相信这些结果。

我们如何处理这个问题?他们只是复制了从Robotium到Espresso的所有内容,一切都变得不错了……实际上,没有。

为了解决这个问题,我们不仅重写了Espresso上的所有内容,而且开始使用API​​进行各种操作,例如上载照片,创建帖子,添加到朋友等,进行快速登录,使用了可直接进入所需屏幕的DIP链接。,当然,我们分析了所有测试用例。

现在,测试运行如下所示:



您可能会注意到红色测试仍然存在,但是请务必记住,这些测试是在生产环境中运行的端到端测试。我们限制了应用程序主分支中可以包含的测试数量。

现在我们有了稳定的测试和扩展。但是,测试基础结构仍然与测试紧密相关。同时,由于期望进行端到端测试,CI繁忙,其他程序集可以排队等待空闲代理。此外,还没有明确的并行启动方案。

上面提到的原因成为了QueueRunner开发的推动力-这项服务使您可以在不阻止CI的情况下异步运行测试。要工作,他需要测试并测试APK,以及一组测试。接收到必要的数据后,他将能够组织队列中的运行,分配和释放所需的资源。QueueRunner将运行结果下载到Jira和Stash,并通过邮件和Messenger发送。

QueueRunner有一个测试流程-它监视测试的生命周期。现在,我们使用的默认流程包括五个步骤:

  1. 接收装置。此时,设备管理器通过协调器请求一个真实或虚拟设备。
  2. . APK , – , .
  3. ,

因此,五个简单的步骤就是我们服务中整个测试生命周期。



QueueRunner给我们带来了什么好处?首先,它最大程度地利用了所有可能的资源-可以扩展到整个服务器场并快速获得结果。其次,有了奖金,我们就有机会控制测试的顺序。例如,我们可以在一开始就运行最长或最有问题的测试,从而减少等待它们运行的​​时间。

QueueRunner还允许您进行智能重新托盘。我们将所有数据存储在数据库中,因此我们可以随时查看测试的历史记录。例如,可以查看测试通过与否的比率,并确定原则上是否值得重新启动测试。

QueueRunner和Devicemanager使我们能够适应资源量。现在我们可以扩展到整个服务器场,这要归功于使用仿真器,也就是说,几乎无限数量的虚拟设备使我们有机会运行更多的测试,但是如果由于某种原因资源不可用,服务将等待它们返回并且不会丢失启动消息。我们仅使用对我们可用的资源,因此,一段时间后仍会获得结果,并且不会阻止CI。最重要的是,现在测试基础架构和测试是分开的。
现在,为了在Android上运行测试,您只需要给我们提供一个测试APK和一个测试列表。

从虚拟机上的Selenium场到在云中启动Android测试,我们已经走了很长一段路。但是,此路径尚未完成。

开发过程


让我们看看测试基础架构与开发流程之间的关系,以及测试人员和开发人员如何看待它。

我们的Android团队使用标准的GitFlow:



每个功能都有其自己的分支。主要开发发生在开发分支。决定创建新超级功能的开发人员将在自己的分支机构中开始开发,而其他开发人员可以在其他分支机构中并行工作。当开发人员认为已经准备好世界上理想的,最佳的代码并且需要尽快将其发布给用户时,他会在开发中提出拉动请求,自动组装单元,运行单元测试和组件测试。同时,将APK组装起来,发送到QueueRunner,然后运行端到端测试。之后,运行测试的结果将交给开发人员。

但是,很可能在开发中创建了特征分支之后,会有很多提交。这意味着开发可能不再像以前那样。因此,预合并首先发生-我们将开发合并到当前的功能分支中,正是在这种过早的状态下进行组装,单元测试,组件测试,端到端,并根据这些结果进行报告。因此,我们了解了该功能在当前版本的developer中的功能,如果一切正常,则将其发送给用户。



报告中


这就是Stash报告的样子:



我们的机器人首先写道测试已经开始,并且在测试通过时会更新消息,并添加已通过的数量,已下降的数量,已知的错误的数量以及易碎测试的数量。他在Jira中写了同样的东西,并添加了一个链接来比较发射。

这是两个启动的比较的外观:



在这里,将功能分支中的当前运行与开发中的最后一次运行进行比较。它包含有关正在运行的测试数量,匹配问题,下降的测试以及处于一种状态并切换到另一种状态的不稳定Flaky测试的信息。

如果至少一个单元测试或超过端到端测试的某个阈值下降,则合并将被阻止。

为了了解测试是否稳定下降,我们比较了跌落痕迹的哈希值,然后才对它们进行了初步清除,只保留了行号。如果哈希匹配,则这是相同的跌落,如果它们不同,则跌落很可能会不同。

摘要


因此,我们实施了稳定,容错的解决方案,可以很好地扩展到我们的基础架构。然后,将生成的基础结构进行了Android测试。设备管理器在这方面为我们提供了帮助,它可以帮助我们与真实设备和虚拟设备一起工作,以及QueueRunner,它可以帮助我们分离基础架构和测试,并且在测试期间不会阻塞CI。

看来,2016年的测试运行时间为一周-从五十分钟或更长时间。



现在就是这样:



该图表显示了每个工作日平均2个小时内的运行情况。运行时间最多减少了15分钟,运行次数明显增加。

All Articles