赞
踩
随着美团到家业务的发展,系统复杂度也在持续增长。测试用例数量近两年增长约一倍,单端数量超过 1 万 2 千条,而研发人员的工作从大部分时间在开发,转变成一半时间在开发、一半时间在模拟环境和自测。因此,引入自动化测试就显得十分有必要,本文介绍了美团外卖在自动化测试方向做的一些探索和实践,希望对从事相关领域工作的同学能够带来一些启发或帮助。
美团外卖的业务场景比较多元化,除了外卖自身的业务,还作为平台承接了闪购、团好货、医药、跑腿等其他业务。除此之外,在全链路动态化的大基调下,外卖各个页面的技术形态也变得越来越复杂,除了 Native 代码,还包括 Mach(外卖自研动态化框架)、React Native、美团小程序、H5 等,不同技术栈的底层技术实现不同,渲染机制不同,进而对测试方式要求也有所不同,这也在无形中增加了测试的难度。下图汇总了美团多业务、多技术、多 App 的一些典型场景。
在产品交付上线的过程中,测试的占比也是非常大的,甚至大于总时长的 30%。如下图所示,整个测试包括了冒烟测试、新功能测试、二轮回归测试、三轮测试。然而,现在需求测试绝大部分还是采用非自动化的方式,这就使得人力成本变得非常之高。
另一方面,相比于 2018 年,2022 年的测试用例数量增长近 3 倍,已经超过 1 万 2 千条(如下图所示)。同时,外卖的业务是“三端复用”,除了外卖 App,还需要集成到美团 App 和大众点评 App 上,这样一来,测试工作量就翻了 3 倍,业务测试压力之大可想而知。如果按照当前的增长趋势持续下去,要保障外卖业务的稳定,就必须持续不断地投入大量的人力成本,所以引入能够支持外卖“多业务场景”、“多 App 复用”、“多技术栈” 特点的自动化测试工具来提升人效和质量,势在必行。
为了解决外卖面临的测试困境,我们尝试去探索一种零学习成本、低维护、高可用的自动化测试方案,能够支持外卖复杂多变的测试场景,它必须同时满足下面几点要求:
自动化测试工具那么多,自研是重复造轮子吗?
针对终端的 UI 自动化测试工具 / 平台可谓“屡见不鲜”,市面上也有很多相对成熟的方案,相信大家都有用过,或者至少有所耳闻,但这些方案是否能真的满足我们提效的诉求呢?以下我们挑选了三类非常具有代表性的自动化测试工具/平台:Appium、Airtest Project、SoloPi 进行了分析,来帮助大家对自动化测试技术建立一个认知:
Appium 是一个开源工具,用于自动化测试 iOS 手机、Android 手机和 Windows 桌面平台上的原生、移动 Web 和混合应用。它使用了各系统自带的自动化框架,无需 SDK 集成,Appium 把这些系统本身提供的框架包装进一套API —— WebDriver API 中,可以使用任何语言编写 Client 脚本向服务器发送适当的 HTTP 请求。这让不同技术栈的人员都能快速上手编写测试用例,可以选择自己最为熟悉的语言,但是对于没有语言开发基础的人来说,还是有一定学习成本,而且这种方式在多人协作时并没有太大作用,为了保证自动化用例的可维护性,团队内部应该需要统一脚本语言。值得一提的是:Appium 在 iOS、Android 和 Windows 测试套件之间可做的一定程度的复用代码。但是由于不同端界面及元素定位的差异,这往往是不现实的,更无法保证测试的准确性,所以这种所谓的“跨端”就变得毫无意义。
Airtest Project 是由网易游戏推出的一款自动化测试平台,除了支持通过系统自带的自动化测试框架,还支持了通过图像识别的方式,对于非基于原生 UI 系统的一些游戏引擎提供了 SDK 的支持。其上手难度稍低,可以一定程度上通过 IDE 进行相关操作来生成简单的脚本指令。Airtest 虽然基于图像进行控件识别,为跨端提供了一定的可能性,然而图像识别并不能达到人眼识别的准确度,除此之外移动端页面的构成和游戏页面也存在不小的差别,页面元素的展示规则和样式受屏幕分辨率影响较大,单纯依靠图像识别来进行元素查找成功率不高,无法保证测试的准确性。
SoloPi 是一个无线化、非侵入式的自动化测试工具,通过录制回放的方式进行 UI 自动化测试,SoloPi 虽然只支持 Android,但是在录制回放的这种方式中,还是极具代表性的。传统的自动化测试工具由于需要编写测试脚本,所以存在着一定的上手难度(Airtest 还是存在代码编辑的),便产生了 SoloPi 这种纯基于录制回放的自动化测试方式,将用例的所有操作事件进行录制,生成一个完整的录制脚本,通过对脚本的回放来还原所有的操作,从而进行自动化测试。但是,这种方式只能记录操作,而不能记录数据,在外卖这种数据驱动展示的场景下无法满足测试要求。并且外卖的业务要复用到美团 App 和大众点评 App 中,不同 App 存在部分视图和逻辑性的差异,SoloPi 也无法支持我们“一端录制多端回放”的测试场景。
可以看出,以上这些自动化测试工具/平台对于数据记录,环境模拟、维护成本、跨 App 复用等方面,都是有所欠缺的。所以无论是哪种方案,在易用性、维护成本、稳定性、可扩展性以及最终的测试效果上,都无法满足我们对自动化测试的需求。我们并不是为了自动化而自动化,而是要解决实际的提效问题。
那么,怎样才能确定一个自动化工具/平台的可用性,并长期落地去使用自动化,带着上述提到的较高门槛的上手成本、操作繁琐的环境模拟、差强人意的测试成功率、定位模糊的测试缺陷、难以维护的用例脚本等几大重要痛点,本文我们将介绍美团外卖自研的测试平台:AlphaTest,都具备哪些能力以及是如何解决这些问题。
所谓的 录制-回放 技术,就是先由手工完成一遍需要测试的流程,同时由计算机记录下这个流程期间客户端和服务器端之间的通信信息,这些信息通常是一些协议和数据,并形成特定的脚本程序 (Script) 。然后在系统的统一管理下同时生成多个虚拟用户,并运行该脚本,监控硬件和软件平台的性能,提供分析报告或相关资料。这样,通过几台机器就可以模拟出成百上千的用户对应用系统进行负载能力的测试。 录制第一次执行测试用例时的键盘和鼠标操作,然后在需要重新执行这些测试时回放一次。
一个自动化测试工具/平台能不能用起来,取决于他的上手成本和稳定性,即使工具的测试稳定性做的再好,使用的门槛高也会让人望而生却,反之亦然。所以 AlphaTest 平台为了上手简单,降低使用成本,采用了 基于录制回放 的方式进行设计,并且 弥补了常规录制回放无法编辑 的痛点,同时在手势操作的基础上增加了 数据录制。整合美团系 App 的特性增加了环境模拟、跨 App 支持、混合技术栈的支持等能力,在使用简单的同时,也保障了用例的可维护性、测试的准确性等。
注:这里我们将生成的自动化脚本统称为 指令,将平台生成的用例统称 自动化用例,将录制回放变成 可视化的脚本指令,让用例变的易懂、易维护。
录制回放本身是一连串的操作数据的集合,是连续性的、不可拆分,因此几乎不具备可编辑性,这也就导致了用例维护成本极高。AlphaTest 虽然同样基于录制回放的方式生成自动化用例,但是我们将每一步的操作都具化成结构化的指令数据,并提供可视化指令编辑器,以支持查看编辑。
这些可视化的指令,完全通过录制自动生成,也不依赖于任何脚本语言。通过可视化用例指令编辑器,不仅为用例提供了编辑的可能性,同时大大地提高了用例的可阅读性,每一条测试用例在测试过程中每一步都做了什么、当时的界面是什么样的、都有哪些断言校验点,是显而易见的,不会存在像传统图文描述的测试用例那样,出现理解偏差。指令生成演示,手机录制与平台远端录制双模式支持。
指令编辑器:
手机录制演示:
平台远端录制演示:
一键环境模拟,解决操作繁琐的用例执行前的环境准备。
进行一个用例的测试之前,往往需要做大量的准备工作,比如切换 API 环境,定位到某个地点,登录指定账户等。这些需要准备的环境条件我们统称为前置条件。我们知道,前置条件的准备操作通常都不是一两个步骤就可以完成的,比如账号登录/切换:我们需要进入登录页,填写手机号+密码/验证码,点击登录等一系列动作来完成这个过程,非常繁琐,并且每次测试我们都需要准备,重复性高。因此,我们给 AlphaTest 设计了独立的前置条件模块,将用例拆成了两个部分:前置条件 + 操作步骤。
与其它测试框架不同的是,AlphaTest 采用了 SDK 集成,但对业务无侵入的方式,因此可以通过编写白盒代码来实现前置条件的自动配置,只需要在平台添加需要的指令,下发到 SDK 后,即可根据相关指令完成前置条件的自动配置,不再需要重复进行相关的操作。并且这些前置条件支持复用,也不需要每次进行用例准备时的重复配置。AlphaTest 的前置条件,不仅有着基于美团内部服务及底层 Hook 的默认实现,也提供了 API 支持业务方自定义实现,比如实现不同的账号体系。
影响用例执行的不仅是代码,还有数据。
很多时候,自动化用例无法正常执行完成,可能是因为 App 回放时的本地数据及网络数据与录制时的不一致,从而导致用例执行流程的阻塞或 App 界面展示的不同。这也是大多数自动化测试工具/平台测试通过率不高的主要因素,因此要保证测试成功率,我们需要控制变量,排除由数据产生的影响。
App 运行依赖的数据,有两部分:本地数据和网络数据:
目标定位的准确性与手势定位的精准性。
UI 自动化测试的本质就是代替人去自动的做一步步的操作(点击、长按、输入、滑动等)。录制与回放过程的操作能否一致,是否精准,直接影响测试的成功率,决定了工具/平台的可用性。
操作行为是否一致首先需要确认操作目标是否一致。与一般测试工具 / 平台不同的是 AlphaTest 采用了 ViewPath + 图像 + 坐标 的多重定位方案。得益于 SDK 集成的方式,我们的 ViewPath 可以记录更多的元素视图特征和执行不同的匹配策略。定位过程中会优先使用 ViewPath 进行目标控件检索,当目标控件查找异常时,会结合图像匹配和坐标匹配的方式进行兜底查找,来确保界面变化程度不大时,也能准确的查找到目标控件。
图像识别示意图
有了基于控件的目标定位之后,对于一些常用简单操作手势,比如点击、长按、断言、甚至输入都可以做到很好的支持,只需要找到对应的控件,在控件所在位置下发相应的触摸事件即可。我们知道,App 真正接收的触摸事件是屏幕上一个个精准的触摸点,在系统处理后,分发给当前 App 窗口,App 在接收事件后再继续分发,直到找到事件的最佳响应者,后续通过响应者链对事件消化处理。那我们要还原一个触摸事件的坐标点要如何确定呢?由于我们确定的只有控件,所以这个点自然而然就成了控件的中心点了。
大多数情况下,这些都可以很好地进行工作,但是对于一些多响应控件重叠的情况,可能会产生预想不到的操作误差。为了解决这样的问题,我们把控件定位与坐标定位进行了结合:基于纯坐标的定位 是一种定位精准度非常高的定位方式,但是稳定性非常差,只有在屏幕分辨率完全一致且回放页面控件位置完全一致的情况下,才具备足够的可靠性,但这往往是不现实的,对测试环境机器量要求过高。
基于控件的定位,又存在着精准度不够的问题。使用坐标定位,如果定位区域足够小的话,那么受屏幕尺寸的影响就会越小,只需要确定在小范围内的相对位置即可。而基于控件目标的定位,恰恰可以把目标区域缩小到一个指定区域,我们刚好可以将二者结合起来,同时解决定位精准度和稳定性的问题。
对于复杂手势的支持,我们同样可以采用微分的方式,将一个复杂手势拆成多个简单手势的组成,比如我们可以将一个滑动操作的定位拆成两个部分:起始位置和终止位置,而这两个位置的定位,就变成了两个普通的单点手势操作定位了,可以通过上面提到的一个目标控件+相对坐标的形式进行定位。核心思想都是 将基于屏幕坐标点的定位操作,缩小到目标控件的区域范围内,以达到不受设备分辨率的影响,实现操作行为一致的效果。
手势识别示意图
测试全流程记录,问题溯源一键即达。
测试的目的是保证 App 运行的稳定,测试过程中出现 Bug 导致测试未通过时,需要溯源问题原因,发生的场景,乃至具体的执行步骤。这也是大多自动化测试工具/平台所欠缺的,即使发现了问题,排查工作也很困难;这个问题在手工测试的时候,更为严重,往往因为很多缺陷无法复现而难以定位。
AlphaTest 的自动化用例最小执行单元是操作指令,我们将测试过程的每一条指令的执行状况和过程中的界面快照进行了记录,并在指令执行失败时,对异常原因进行了初步分析。然后将整个用例的执行组合成了一份完整的测试报告,可快速溯源问题步骤。除此之外,我们还增加大量的日志上报,并将整个用例测试过程进行了视频录制,来进一步帮助疑难问题的排查。真正做到了用例回放测试可溯源。
自动化用例需要持续地投入人力来维护么?架构升级,页面重构,用例需要全部重新录制么?
因自动化工具/平台众多,阻碍长期落地使用的一大问题是用例维护成本高,很多工具/平台让我们即便是使用上了自动化,但还需要持续投入人力维护用例的更新,最终的提效收益微乎其微。对于用例更新维护,我们可以梳理划分成三个场景:
需求发生重大变更,整体的业务执行流程及相关的校验点都需要进行大量的调整。对于这种情况,无论是何种自动化测试工具/平台,都是需要正常进行用例变更重录以适应新的需求。
需求发生略微变更,业务流程基本一致,需要调整的校验点、操作以及数据或不影响整体流程的步骤。对于此场景,AlphaTest 通过指令编辑器与操作录制,支持指令增删改以及数据和场景的还原,帮助用户快速的进行用例调整,而无需重新录制用例。例如:修改网络数据字段、视图变更路径、断言替换目标等。
和业务需求不同,我们的技术实现也会发生迭代。随着 App 技术架构不断的演进,经常会面临着架构升级,页面重构甚至技术栈变迁等这样的技术升级。这些变动需要覆盖大量的测试用例,其中大量的自动化用例又可能会因为变动而导致失效,需要重新录制。为此,AlphaTest 设计一套利用相近分辨率机器进行用例自动修正的功能:利用图像 + 坐标进行二次识别定位,元素定位成功并校验通过后,生成新的 ViewPath,更新对应的用例指令,对用例进行自动修复,修复后可在任意回放。
同一份代码运行在不同的App上,是否需要重新编写多份用例?
美团系的一些业务可能会复用在多个 App 上。比如外卖有独立 App,但同时也要复用到美团和点评 App 上,这些功能,几乎共用一份代码,而测试人员却不得不对每个 App 上的业务功能都进行测试,维护多份用例。由于业务本身实现是一致的,那我们可以通过适配不同 App 之间的差异,来让一个业务 Case 可以横跨多个 App 回放,这便可以将成本缩减好几倍,这些差异主要体现在:
AlphaTest 平台支持 App 维度各项差异数据配置,当 SDK 检测用例回放环境与录制环境不一致时,会自动进行映射适配,从而让用例运行到了不同 App 上。
除了功能测试,我们在日常开发和测试的工作中,还会面临另外一个比较重要的问题就是埋点测试。因此,我们在自动化的基础上扩展出 埋点自动化测试。埋点自动化测试的核心思想是,通过对比录制时期和回放时期的埋点 上报时机 和 上报参数 进行判断。为了保证埋点自动化测试的稳定性,我们主要采用以下的障机制:
字段规则配置:埋点自定义参数千姿百态,甚至有些字段每次代码执行都不一致,如果进行完全匹配结果注定是失败的,所以我们在 AlphaTest 平台提供了埋点字段规则配置功能,通过人为设置的方式来避免埋点自定义参数校验失败。App 重启进入录制状态时,用户就可以操作 App,平台会记录用户的操作行为,当产生相应的埋点日志的时候会将日志信息打印在日志区域(如下图所示),在该过程中也会对埋点日志进行一定的校验。重点将操作时机、埋点日志一并保存到服务端。
埋点时机校验:针对时机校验,程序并不支持埋点曝光的"1px曝光",“下拉刷新曝光”,“页面切换曝光”,"切前后台曝光"这些规则,主要的原因是每一个业务方在对埋点曝光的规则都是不一致的,而且该规则的实现会极大耦合业务代码。在针对时机校验我们目前只支持:
结果校验:回放完成后,我们会对比录制和回放时的埋点数据,根据配置好的字段规则校验埋点上报是否符合预期。
AlphaTest 的核心测试流程始终聚焦在用例的录制与回放环节,整个流程涉及到自动化任务触发、回放集群调度、断言服务、消息推送等核心模块。
以 UI 自动化和埋点自动化的流程为例,AlphaTest 以业务团队为基本单元,可以和各团队的测试用例进行关联,定时同步状态。同时利用需求评审线上化做为基础,将自动化用例和研发流程中的 PR、集成打包、二轮回归等节点相结合,定时触发自动化用例并将结果报告推送给相关负责人。
录制用例:
用例回放:
回放计划:
二轮回归测试中,回放用例数量多达几百条,为了做到全流程的自动化,我们提供了回放计划的概念,可以将多个自动化用例进行编组管理,每一组就是一个回放计划。触发一个计划的回放即可自动触发计划内的所有自动化用例。整个计划都执行完成后,会通知到指定的计划负责人或群组。
在整个外卖 C 端敏捷迭代的流程中,打包平台主要承接了业务需求发起到需求交付的流程,作为 AlphaTest 的上游平台,可以提供打包信息并触发自动化用例回放任务。以下简单展示 AlphaTest 与敏捷协同平台的交互流程:
整个测试过程真正的解放双手,才能算的上是自动化。因此,我们着手搭建了自己的自动化机器集群,可以 24 小时不间断的执行测试任务。为了保证任务回放能够顺利完成,我们在不同阶段增加了相应的保活策略。在极大程度上提高了任务执行完毕的成功率。
用例断言是整个自动化用例验证的核心步骤,我们的断言服务依据用例的实际情形可以分别进行文字与图像的断言。其中图像断言服务依托于自建的图像对比算法服务,可以高效进行录制回放断言图像的对比,图像对比准确率可以达到 99% 以上。
录制阶段:
回放阶段:
图像服务:图像对比模型采用基于度量学习的对比算法,将图像对的一致性判别转换为图像语义的相似度量问题。度量学习(Metric Learning
),也称距离度量学习(Distance Metric Learning,DML
)属于机器学习的一种。其本质就是相似度的学习,也可以认为距离学习。因为在一定条件下,相似度和距离可以相互转换。比如在空间坐标的两条向量,既可以用余弦相似度的大小,也可以使用欧式距离的远近来衡量相似程度。度量学习的网络采用经典的 Siamese
结构,使用基于 resnext50
的主干网络提取图像的高级语义特征,后接 spplayer
完成多尺度特征融合,融合后的特征输出作为表达图像语义的特征向量,使用 ContrastiveLoss
进行度量学习。
resnext50
网络是使用 ImageNet
的预训练模型。ContrastiveLoss
,它是一种在欧式空间的 pair based loss
,其作用是减少一致图像对距离,保证不一致图像对的距离大于 margin
,其中 margin=2
。[0, 1]
,作为输出的图像对相似度。消息推送作为回放流程的最终环节,我们依赖于美团内部自建的消息队列服务与 OA SDK 消息推送能力,可以进行测试报告的实时推送。在此之上,还可以针对不同团队的推送诉求,做消息模板的定制化。
外卖 C 端主要承担了用户在 App 端点餐、下单、配送的所有核心流程,场景繁多、业务复杂,这也给测试人员的版本测试带来了诸多挑战,其中最核心也最耗费人力的便是二轮回归测试环节。目前,C 端采用的双周敏捷迭代的开发方式,每个迭代周期给测试人员用来进行二轮核心流程回归的时间为三天,为此 C 端测试团队投入了许多人力资源,但即便如此,仍难以覆盖全部流程;而 AlphaTest 的设计初衷也正是为解决此问题:UI测试流程全覆盖及自动化验证。
用例的转化与维护
AlphaTest 在外卖 C 端测试团队的落地初期,我们采用了共建的模式,也就是业务研发人员与对应测试人员共同来进行用例录制与维护的工作;推荐这种工作模式的核心原因是,在 C 端功能迭代流程中的二轮周期的原有工作模式为,研发人员进行二轮冒烟测试,完成测试之后提交二轮包交由测试人员进行二轮回归测试,所以这本来就是一个双方都需要参与的环节;而二轮测试作为版本上线前的最重要一个测试流程,保证核心流程的正常也是测试人员与研发人员所关心重点。
经过多轮的使用与磨合之后,这种模式被证明是行之有效的,在整个 C 端二轮用例的转化过程中,测试人员主要负责了用例的录制与迭代流程,研发人员则主要负责版本回放数据的统计及问题用例的发现与解决。
外卖二轮落地情况
目前,AlphaTest 已经在外卖多个业务落地,支持了大于 15 个版本的二轮回归测试,用例覆盖率达到 70%。现已覆盖了 Native、Mach、React Native、美团小程序、H5 技术栈的测试工作,能力上可进行支持:UI 自动化测试、埋点自动化测试、动态化加载成功率自动化测试、无障碍适配率自动化测试。
未来,我们会朝着“智能化”和“精准化”两个方向探索,覆盖更多测试场景的同时,更进一步提升测试人效。
[1] https://appium.io
[2] http://docs.seleniumhq.org/projects/webdriver
[3] http://airtest.netease.com/index.html
[4] https://github.com/alipay/SoloPi
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。