写点什么

Android 手机 QQ 的 UI 自动化实践,BAT 面试 & 高级进阶

作者:嘟嘟侠客
  • 2021 年 11 月 27 日
  • 本文字数:4143 字

    阅读完需:约 14 分钟

封装模式




在上一步环节中,我们虽然确定了自动化框架,但是框架只提供底层的驱动能力,如果无统一封装模式进行规范,随着用例的增多会变得难以维护,所以我们需要一个统一模式来封装细节,可以使 testcase 更稳健,不需要大改动。即我们需要对 UiAutomator API 进行二次封装。


业界最常见的一种封装模式是 Page Object 模式,“页面即对象”。这种封装模式把一个页面看做一个对象,把页面上的控件(按钮、图片等)元素当做对象的属性,把对页面上的控件操作(如点击某按钮)当做对象的方法。这种封装模式的优势是维护简单,对于页面的某些改动,只需要维护该页面对应的对象。劣势是代码复用率较低,不利于大规模铺量


还有一种常见的封装模式是 Scene 模式,“场景化封装”。这种封装模式就是按照用例的场景,也不需要 API 的二次封装,简单粗暴去实现。这种封装模式的优势是简单粗暴,可读性高。劣势是代码复用率低,十分冗长


我们的痛点是,需要快速铺量,那按照用例场景,所见即所得的代码方式,的确是很快,但是我们需要对该模式规范化。结合测试用例的 3A 原则(Arrange、Act、Assert),我们创造了一种新的封装模式 QTS(QQ Testcase Service)。


自动化框架 QTS




我们在写测试用例的时候,是按照用户角度,从一个个控件元素触发,经过一个个场景页面,最终验证某一个结果。那为什么不直接把上面的元素触发(Action)、场景页面(View)、验证(Check or Assert)自动化呢?这样就可以快速实现任意一个用例了,因为自动化代码和测试用例的文字描述是一一对应的。


QTS 是 Scene 模式的进一步改进。我们抽象出测试用例的 3A,抽象出控件动作(Action)、页面元素(View)、断言(Check)这三个最基本接口,同时因地制宜,结合手 Q 复杂的环境,又抽象出场景流(Workf


《Android 学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享


low)、环境(Env)接口。


TestBase 是全部测试用例类的基类,包含了测试用例的一些通用属性和方法。它的属性包括单例模式的 action,env,check,qqAcount 等,方法包括登录 QQ,初始化手 Q 环境等。所有的测试用例类都继承这个类。



  • Action:基本操作事件的接口,在该接口中,负责封装实现所有的动作事件,比如点击、长按、输入框输入、滑动等事件。底层设备驱动能力由 UiAutomator 框架的 uiDevice 类提供。


void click(String control); // 点击某个控件 void longClick(String control, long clickTime); // 长按某个控件 void swipeUp(int steps, int swipePixelLength); // 页面上滑 …… ……


  • View:控件定义与查找接口,在该接口中,负责封装所有的设备可检索的控件元素,并提供检索方法。底层的定义能力由 UiAutomator 的 BySelector 类提供。


/** * 获取 control 的对象 * * @param controlName control 的中文定义 * @return UiObject2 对象 */ UiObject2 getControl(String controlName); /** * 获取指定 instance 以及 id 的 Object(适用于页面中有多个控件拥有相同 id 的情况) * * @param controlName control 的中文定义 * @param instance 控件的数值顺序 * @return UiObject 对象 */ UiObject getInstanceControl(String controlName, int instance); …… ……


  • Check:断言接口,之所以没有叫 Assert,是为了和 Juint 的 Assert 做一个区分。在该接口中,提供了对于检测元素存在、不存在、判真、判假等方法。底层断言能力由 Junit 的 Assert 提供。


/** * 检查控件是否存在 * * @param control view 层封装的控件中文描述或者控件唯一 text */ void exist(String control); /** * 检查控件是否不存在 * * @param control view 层封装的控件中文描述或者控件唯一 text */ void notExist(String control); /** * 检查是否成功登陆 * * @param id 消息 tab 的 feeds 数 id,用来判断消息 tab 是否完全家在成功 */ void loginSuccess(String id); …… ……


  • Env:环境接口,因为手 Q 复杂的环境,所以特意把环境相关的方法抽象出来,同时在该接口中,还有直接实现后台接口的方法,比如加好友的接口、删除好友的接口、一键建群的接口、一键销毁群的接口等。


/** * 创建群(无需验证信息), 测试账号需要添加 oidb * * @param uin 需要创建群的群主 uin * @param groupName 需创建群的名字 */ Response createGroup(String uin, String groupName); /** * 一键加好友 * * @param fromUin 申请加好友的号码 * @param friendUin 需要添加的 uin */ Response addFriend(String fromUin, String friendUin); …… ……


  • Workflow:场景流接口。这个理解比较困难,可以认为它是一个多 view 的操作集合,主要提供场景流的一些方法,比如一键进入聊天页面(手 Q 中称之为“AIO”)等。


/** * 通过接口进入 AIO * * @param uin 群或 C2C 的 uin * @param uinName 名称 * @return 执行状态 */ void openAIO(ActivityTestRule<splashactivity> activityTestRule, QQAppInterface app, Long uin, String uinName);


此外,QTS 还提供了一些通用能力,比如 log 等。


编写测试用例




有了 QTS,根据测试同学提供的用例来自动化,就变得简单明了。比如某一个测试用例,需要打开手 Q 钱包页面,检查充值记录。那么利用 QTS,就可以完全模拟用户的手工操作,一步步实现用例。


public class AccountTest extends QTSBase { // 1. 实现手 Q 钱包进入的 workflow private final QWalletHomeWorkflow qWalletHomeWorkflow = new QWalletHomeWorkflow(); @Override public void setView(ArrayList<view> viewList) { // 2. 添加这个用例涉及到的 view 页面 viewList.add(new MsgTabView()); viewList.add(new QWalletHomeView()); viewList.add(new QWalletAccountView()); } // 3. 登录手 Q @Before public void setUp() throws Exception { loginQQ(activityTestRule, "qq_uitest"); } // 4. 编写用例 @Test @CaseAdditionInfo(tags = {"FT=UI 自动化", "模块=QQ 钱包", "功能=点击 Q 币", "测试分类=功能", "测试阶段=全用例", "管理者=neoyu", "用例等级=P0", "用例类型=1", "被测函数=null", "用例描述=在账户页点击 Q 币", "版本=850", "手工用例 ID=748878937694273536" }) public void testShowQCoinRechargeRecord() { // 5. 这里的代码所见即所得,简单明了,即使不注释,也可以很快读懂用例的步骤与含义,也方便责任人交接 qWalletHomeWorkflow.openQWalletAccount(); action.waitThenClick("账户页 Q 币个数"); check.exist("充值记录标题"); check.exist("全部交易"); } }


录制回放工具


======


背景


--


光有上面的 QTS 框架,虽然写自动化用例已经很快了,但是还是达不到部门的目标(毕竟部门要实现在半年内把手 Q 欠了多年的技术债补齐),在这种压力下,就必须引入新的工具、新的方法。我们调研了公司内外的方案,最终使用了公司内部开源的录制回放工具。录制回放工具是一个通过手工录制,然后回放校验断言的自动化测试工具。


基本原理





其实核心原理并不复杂,在录制的时候记录下元素、对应的操作、网络与 IO 数据,在回放的时候 mock 数据并回放操作。这里要注意,因为涉及到复杂 mock 与元素的处理,这个工具是侵入式的,需要维护一个手机 QQ(录制回放版本)的打包流水线。


实践


==


1.手工测试用例




目前手 Q 的全部测试用例都托管在公司内部的 tcm 平台上,我们的目标就是把 tcm 平台上,部分 P0 用例实现自动化。


对于新功能,由外包同学或者测试同学来录入手工用例,确定优先级。我们之后会针对 P0 用例,考虑自动化。


2. 编写自动化用例




直接利用 QTS 编写。需要注意的是,这里的 CaseAdditionInfo 是利用了公司内部的终端自动化测试平台的能力,在 CI 系统上配置了流水线,会扫描代码仓库,当扫描到这个注解的时候,就会认为这是一个测试用例,然后把这个测试用例的相关信息上传到该平台。


@Test @CaseAdditionInfo(tags = {"FT=UI 自动化", "模块=群", "功能=群活跃排行榜", "测试分类=功能", "测试阶段=全用例", "管理者=stancheng", "用例等级=P0", "用例类型=1", "被测函数=null", "用例描述=活跃排行榜为空", "版本=850", "手工用例 ID=730700977215709184" }) public void testEmptyGroupRankingList() { // 打开群设置 aioWorkflow.openGroupAio(activityTestRule, app, "272329539", "UITest 群 4"); // 等待一下,群荣誉需要拉取配置 delay(5); // 打开群荣誉 aioWorkflow.enterChatSetting(); boolean isSuccess = groupSettingWorkflow.enterHonorSetting(); // 如果失败,那就返回再进入 while (!isSuccess) { action.back(); aioWorkflow.enterChatSetting(); isSuccess = groupSettingWorkflow.enterHonorSetting(); } // 检测是否存在虚位以待 delay(5); check.exist("虚位以待"); }


3. 管理自动化测试用例




自动化用例的管理主要依托终端自动化测试平台,在这里实现了用例的解析、上传、流水线绑定、测试用例集管理、数据看板等操作。


提升稳定性的一些方法


==========


1. 后台接口代替 UI 操作




手 Q 里面很多场景都是超级复杂的,比如加好友后自动发消息,加好友这个操作本身就很复杂,如果场景累加的话,那 UI 自动化的运行时间将大大延长,并且每多一个 view 就增加检索失败的风险。所以这时候,就需要和开发同学协商,把加好友这一步,做成接口,在客户端可以直接调用。这些接口,我们统一封装在 Env 接口类中。


2. 重试机制




UI 自动化用例中,偶现某个元素或操作事件没有生效的情况,这和设备有很大关系。在没有更多预算的情况下,就需要增加一些重试,比如下列用例,其中的 retryCount 就是一个重试机制:


public void clickFile() { clickPlusBtn(); UiObject2 object2 = uiDevice.findObject(By.clazz(Constants.CLASS_RADIO_BUTTON)); int retryCount = 0; while ( object2 == null && retryCount < 5) { retryCount ++; clickPlusBtn(); object2 = uiDevice.findObject(By.clazz(Constants.CLASS_RADIO_BUTTON)); } plusAreaClick("文件"); }

【附】相关架构及资料



往期 Android 高级架构资料、源码、笔记、视频。高级 UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter 全方面的 Android 进阶实践技术,群内还有技术大牛一起讨论交流解决问题。


本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

用户头像

嘟嘟侠客

关注

还未添加个人签名 2021.03.19 加入

还未添加个人简介

评论

发布
暂无评论
Android手机QQ的UI自动化实践,BAT面试&高级进阶