原创: 张志阳 转转 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


↙↙↙阅读原文可查看相关链接,并与作者交流