转转QA 转转 App UI 自动化进化史

笑哼 for 转转QA · June 27, 2018 · Last by 志阳、 replied at September 05, 2018 · 2717 hits

原创: 张志阳 转转QA

一、 概述

背景

每个版本都需要执行大量的老功能回归Case,重复工作量较大

随着App功能的逐渐增加、回归测试点逐渐增多,在保证测试覆盖度的前提下,整体的回归测试时长在增长,增加了测试压力

在针对老功能回归测试的过程中,因回归测试点比较多,可能存在测试点漏测的情况

目标

覆盖大部分的回归测试Case,帮助大家执行部分功能的回归测试,减少回归测试的人工成本

利用UI自动化测试 自由分配、随时可执行的优势,增加已有功能的测试频率,在版本开发工程中,尽早发现因新更改影响已有功能的情况

不局限于已有功能的验证,利用UI Case的操作场景,在执行过程中进行其他数据的收集,供其他测试类型使用

对线上已发布的版本,进行主流程功能监控

二、 框架介绍

1、UI自动化框架

UI自动化测试框架有很多,基于以下几点考虑,选择使用Appium框架

转转Android & iOS 的App功能交互&设计始终保持一致,使用Appium可以保证一套操作逻辑,两端都可以使用,减少Case创建&维护成本

Appium支持 Native 、Webview 、混合页面的测试

属于外部测试框架、结合支持多种语言的优点,更方便扩展使用

2、UITest框架结构

框架是UI的基础,框架的稳定及易用,决定了UI自动化的整体流程的效率及稳定

3、业务Case

结构

参考PageObject设计模式,将Case的结构进行拆分管理,解耦的同时,更便于维护

case存放位置

app业务

属于基础业务,存放在UITest框架内部,可供其他业务使用部分已封装好的操作场景

其他业务

为了支持多业务使用框架,避免共同在单一工程中维护代码时互相影响,对框架进行了扩展支持

每个业务可以单独新建独立的工程进行Case的编写及维护。只需将UITest框架放置在工程内,将保存测试集的suite文件通过传参 或 在suite文件中调用UITest执行接口,就可以触发执行

4、测试结果

本地存储

存储位置:每次执行都会在工程-report目录中创建独立的文件夹存储测试结果

存储内容:设备执行Log(框架执行过程中的log,非设备本身的log)、失败Case截图、便于汇总查看的报告文件(html)

线上存储

每次的执行结果都会上报结果平台,存到数据库中,便于查看历史记录及详细的执行数据

三、 UI自动化进化过程

1、控件定位方式

iOS Native控件定位方式

初期:主要以XPATH为主 + Text 的方式定位控件,XPATH 定位较慢,App布局改变后需要重新维护

RD帮助补充 控件 NAME属性后:将主要使用XPATH的方式定位,更改为主要使用NAME & Text的方式,降低了控件定位耗时,降低了Case执行耗时

图像识别 方式扩展

初期:iOS和Android存在大量的共用图片、每个控件基本只有一张图片,在不同分辨率的设备上得到的相似度不同,会影响匹配结果判断

为每个平台创建单独目录保存图片:避免相同控件在不同平台上,图像略有不同,不能使用同一张图片识别

同控件根据不同分辨率,分别截图取样:定位控件时,先计算设备分辨率,优先查找同分辨率的图片样本进行识别

通过图片名称查找图片样本:没有通过分辨率查找到对应图片样本后,根据图片名称查找通用图片

支持Webview 控件

初期:只执行了Native 控件的识别及操作

现在:增加多种Webview定位方式的支持,从而增加了对M页功能的较好支持

2、控件操作方法

验证控件是否存在

图像识别

初期:只根据Element中存储的完整图片名称,查找图片

现在:Element中存储的为图片名称关键字,根据平台查找平台目录,优先根据分辨率+名称查找图片样本,未找到再根据图片名称查找

iOS控件增加实际显示位置判断

初期:通过Text/Name 定位的控件,与page_source对比,根据enable & visible的值,判断是否可用,其他定位方式通过Driver.find,查找到就认为可用。实际上Appium 执行时获取iOS的page_source并不稳定,发现同一页面,有时可以获取到iOS 中 当前页面已加载出的所有控件(包含为显示在屏幕区域内的),并不能进行有效操作,并且有些被Tab Bar由于被遮挡而不能正常操作到

现在:增加控件位置的计算、判断是否在屏幕可操作的区域内,若不在有效区域内,虽然可定位到,但因不可操作,也认为其不存在,配合滑动操作,将控件滑动到有效区域再操作

点击方法扩展

初期:只支持Native控件的点击操作

扩展支持WebElement类型

添加专项数据收集支持

滑动方法优化

根据设备屏幕分辨率,计算准确的坐标值,进行滑动

解决iOS滑动不好控制的问题,较好的控制滑动幅度

3、执行策略

触发方式扩展

初期:执行参数较少,基本只在配合CI时使用,本地多数还是直接运行UiTest.py触发执行的方式

扩展更多的执行参数,更自由、方便的控制执行配置,也可以较好的为外部的其他脚本/平台提供支持

封装执行接口函数,供外部工程调用框架执行时使用,参数与命令行参数一致,

多平台同时执行

解决多平台依次执行,整体时间过长,效率比较低的问题

Android / IOS 使用不同的预设起始端口启动Appium,互相不冲突

使用多进程的方式,每个平台启动一个单独的进程用来启动Case执行

利用执行参数 –o 或者 修改config中的optionsystem,控制当次执行时使用的平台

多平台多设备同时执行相同Case

在进行功能测试的同时进行兼容性测试

在每个平台进程内,根据设备列表,为每个设备分配Appium端口,互不冲突

为每个设备再启动一个进程,独立执行Case

每个设备单独统计测试结果、保存、发送报告

利用 –d 参数可以控制使用的设备

多平台多设备分配Case执行

Case 量越来越多,单设备全量Case的执行时长越来越长,多设备分配Case执行,可以提高执行效率、缩短整体耗时

根据Case列表筛选出每台设备都需要执行的初始化Case及 需要分配的Case集,结合设备列表,分配Case集,为每一个设备创建独立的testsuite文件

为每个设备分配一个进程,执行对应的testsuite

当同平台的所有设备都执行完后,以平台为维度,进行结果汇总,保存结果、发送报告

利用 –g 参数可以控制是否分配Case执行

4、整个框架执行逻辑对比

初期:

现在:

5、UICase筛选依据

UI自动化 Case 并不能保证100%的覆盖所有的功能Case,在不同的阶段的Case筛选依据会有所不同

建设初期(欠债)阶段:以回归测试的CheckList为依据,根据功能模块的重要性,设定优先级,逐步添加Case

参与版本周期(进度持平)阶段:新功能Case的添加,优先以冒烟测试用例为依据,筛选出UI Case 覆盖范围,再添加额外的Case

四、未来

在Case可覆盖功能 、执行策略等方面,现有的UITest框架均已满足了基本需求,可稳定使用,后续的工作都为扩展,目的是增强UI 自动化的作用,利用UI自动化做更多的事情

利用UI Case ,获取更多的数据,驱动更多种类型的测试

可视化查看、操作、控制UI 自动化 及相关测试的进行

持续集成、与CI结合、更自由、敏捷的执行

原文链接:https://mp.weixin.qq.com/s/MmoVNyocTuE7pdxZfhQBNQ

共收到 12 条回复 时间 点赞

学习了,能说一下设备管理这部分具体是怎么设计的吗?

笑哼 #2 · June 29, 2018 作者
隐身 回复

STF

看了楼主的思路,感觉还是非常不错的,给贵厂点个赞
有几个问题:
1、能说贵厂数据管理的思路是啥样的?
2、android版本运行起来如果ui2有没有出现不稳定的情况,如果和我一样出现了,可否提供解决思路呢?
提供一点建议:
分布式执行去全量case 时间还是一样久,可以试着全量case随机分配到机器分布式执行,最后结果统一,这样case跑起来会快的多

笑哼 #4 · July 02, 2018 作者
文贤平 回复

针对第一点:Ui自动化case里的数据是在Ui test工程中,另外失败截图、log日志、历史数据等都是在自动化平台上;
针对第二点:不知道你说的不稳定的具体错误,我这边目前没问题,当然刚开始使用时会出现一些问题,不过已经解决了;
另外针对你的建议:
其实是我们这边做的其中之一,我这边分布执行全量case有开关控制,开关打开,假设全量case为n,设备为m,那么每个设备的case数量就是n/m;如果开关关闭,那么每个设备的case数量就是n

想请教下,你们有没有做失败重测这块的工作,如果做了 是怎么做的 给点思路

笑哼 #6 · July 04, 2018 作者

是说运行失败的ui case重新运行么?(失败的case单独记录下来重新再跑一遍)还是说运行失败的ui case怎么处理?(首先确认下是否是bug呗,不是bug的话就是代码的问题)

隐身 回复

现在:
设备管理方面:我们在做一个设备管理平台,已经上线试用,主要是分布式管理,在多台设备上安装Agent服务,实时与设备平台同步信息, 设备平台也会下发任务给Agent服务,指定设备执行特定的任务
设备控制方面:Android 如笑哼所说 暂时接入STF,iOS 还在调研,可能先试用一些各位大佬已开源分享的方案

以前:
UI框架: 执行时,会 获取已连接设备列表,获取当时 预使用的Appium端口占用情况 ,根据执行时设备的选择(配置的设备平台 和 是否指定了设备),为设备分配端口执行
测试平台未接 设备平台时,本地服务异步更新设备连接状态,设备有 是否被占用 & 是否连接 两种状态,用来区分设备是被测试占用,还是未在线不可用,哪些是已连接并且可用的。端口处理同框架。设备基础信息的存储

wtnhz 回复

Ui框架本身,可以设置失败重试次数,当Case执行失败时,会立刻进行重新执行,结果会分开保存。
测试平台,因为框架本身有重试测试次数设置,所以也可以配置重试次数,下发任务执行
测试平台本身,也提供了批量重新执行的策略,在一次测试记录的测试结果页面 或者 测试计划配置页面, 可以一键触发 重新执行,上次执行记录中的所有失败Case,重新执行前,可以更改分配的设备 和 使用的被测应用安装包

文贤平 回复

数据管理:
Case所需测试数据,有专门的文件存储测试数据,有特定的方法提取测试数据,所以编写Case的时候,补充好就可以了。
Case执行所需的前提条件数据:会有方法进行数据创造,之后再执行测试逻辑
Case执行过程数据:Case执行过程中,会产生 框架log ,Case执行log,Device log, 失败时截图,及 Case 视频,log及截图,本地会保存文件,也会在执行结束后通过平台接口,上报给平台存储,方便通过平台查看Case执行过程,Case视频会直接上报平台 ,不会本地存储,文件的存储会使用ftp, 测试结果及执行信息 会存储数据库
Case执行产生的应用数据: 会在测试结束后,通过特定的方式,将产生的测试数据进行清理

Case分量执行建议:
如笑哼所说,框架本身有配置开关控制,是否在使用多设备时,进行Case分量执行,各执行一部分,设备越多,使用的时长会越短
测试平台方面:有一个后续的计划,一直都保留着 Case 在 各个设备 及版本上 成功 / 失败的执行耗时, 可以利用这个数据,在选择Case 列表 和设备后, 根据历史数据,进行计算,计算出,预计最短时长的分配方案,尽量保证各个设备使用的时长相近。

志阳、 回复

我这两天也在搞iOS方面的支持。欢迎交流。

隐身 回复

带上我

隐身 回复

好啊好啊😀

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up