一种 Android 端 Web 多进程情况下支持 Web 自动化测试的方法

作者:陈航特

团队:腾讯移动品质中心TMQ

从2016年开始,应用宝的主体工程就开始往多进程方向发展,至7.0版本发布时主工程已完成多进程改造,而彼时应用宝的子进程基本不涉及UI,自动化测试框架采用Robotium+UiAutomator2.0的方式,Robotium基于Instrumentation注入主要负责单个APP内的自动化测试,UiAutomator2.0支持跨应用的自动化测试,因此彼时应用宝的多进程改造并没有影响到BVT自动化测试。

应用宝Web多进程后,就暴露了目前业界主流自动化测试框架的不足,Robotium支持Web自动化但仅限于注入单一进程,UiAutomator2.0支持跨进程但却不支持Web自动化,其它的支持Web自动化的框架例如Selendroid、Espresso等等在原理上均与Robotium相类似(采用Instrumentation注入执行JS提取Web元素),因此也不支持跨进程的Web自动化。

本文介绍一种在Web多进程情况下支持Web自动化测试的方案。介绍当前Web自动化的简要原理、Web多进程后的问题、相应的解决方案及使用方法。

一、Android端Web自动化原理简介

Android端支持Web自动化的测试框架如Robotium、Selendroid、Espresso等等在原理上基本类似,都是采用Instrumentation注入被测app后,执行js脚本,提取并封装成拥有Web元素的文本信息、id或class等属性、坐标信息等等的WebElement对象。

首先,进入Chrome的MobileEmulation模式,访问例如应用宝中视频TAB的H5页面。

然后,进入Chrome的js控制台:Ctrl + shift + j,执行如下JS脚本:

可以看到浏览器的提示框显示了className为classify classify-tv元素的信息。

可以看到,通过JS注入的方式,我们可以获取网页中的包括文字、tag标签、属性、坐标等等信息。

那么,如果我们也能够在Android上用JS的这种方式获取每个网页元素的信息,然后对这些信息进行封装处理,那么在自动化测试时就可以操作这些Web元素了。

WebChromeClient类在Android中,主要用于辅助WebView处理Javascript的对话框、提示框等等

如上图,以onJsPrompt()为例,当WebView加载网页时,如果有Js调用了onPrompt弹出提示框,则onJsPrompt()将会被调用,该方法中的String message参数即为显示在提示框中的提示语,即如下图中的提示语将传递给message参数

以下是Robotium中的实现:

获取到message后,然后按一定规则对message进行分解,然后封装成WebElement对象

简要原理图如下:

二、Web多进程后的问题

由Android端Web自动化的原理可知,核心是Instrumentation注入后,获取目标WebView,对该WebView执行js以提取Web元素。Web多进程后,Web运行在子进程中,而Instrumentation注入的是主进程,且由于Android的沙箱机制导致在主进程中无法获取子进程中的控件对象,也就是Instrumentation注入后,无法获取H5子进程中的目标WebView,示例图如下:

出现该问题后,解决思路主要有两个方向:

1、让Instrumentation注入Web子进程而不是主进程:经尝试后发现Instrumentation在注入时,会判断当前进程名,即当前进程名需要与测试工程AndroidManifest.xml文件中申明的targetPackage一致,而Web子进程的进程名为主进程包名加后缀的形式,即:com.tencent.android.qqdownloader:web。若直接修改targetPackage,在AndroidManifest.xml申请instrumentation时又不能带:号,因此该方向不可行。

2、将测试app中获取目标WebView及执行js等等模块移植到web子进程执行,再通过IPC跨进程通信将执行结果传回测试app,此方向可行。

三、Web多进程后的支持Web自动化测试方案

上文第二中的第二个方向虽然可行,但结合项目实际情况还需要优化改进方案,在项目侧会有以下要求:

1、应用宝严格控制安装包大小,因此支持Web自动化测试相关代码若移植入子进程,显然会增大不少安装包的大小。那么采用开关控制打包?

2、项目正在做持续交付流程,自动化所测包即为最终希望发布的包,因此测试代码需要对外发布。

终上,最后方案确定为将测试代码采用插件化的方式,将主要实现代码在插件app中实现,应用宝web子进程中只实现少量的调用插件app的代码,对安装包影响小、安全风险可控。方案示例图如下:

另外,由于应用宝使用了手机QQ浏览器提供的TBS(TencentBrowsing Service)浏览服务,在web子进程中可能出现系统WebView或者X5WebView,两者在实现Web元素提取时有所不同,需要区别对待,整体方案的核心逻辑流程如下图所示:

1、测试app发送cmd命令:在Android端Web自动化测试中,要想完全支持Web的测试,除了获取Web的元素外,还有例如获取Web页面的url链接、标题、进度条、上下滑动等等,因此本方案以cmd命令字的方式来区分这些不同的操作。

2、支持Web自动化测试的代码以插件方式实现,子进程收到cmd命令时,需要先判断是否需要安装插件,插件app采用Android工程进行开发,最终编译生成的是一个插件apk,需要安装插件时则从手机上的指定目录安装插件apk。

3、映射ClassLoader:插件app需要能支持X5 WebView的自动化测试,因此插件工程需要引入TBS提供的SDK,但在编译时不打包进插件apk。应用宝内使用X5内核提供的服务时,也是用的TBS提供的SDK,且是以TBS插件形式使用,因此本方案中的插件app在实际运行时要找到TBS SDK中的类时需要做ClassLoader映射。

4、判断当前Web子进程在用的是否是X5 WebView:若是X5 WebView,则走X5 WebView相应的js执行、提取Web元素的流程;若是系统WebView,则走系统WebView相应的js执行、提取Web元素的流程。

5、测试app解析并封装成WebElement:测试app发送的cmd命令为获取Web元素时,插件app提取到的元素是以json数组转字符串形式进行存储,因此解析时该json数组每个元素就对应于一个Web元素,可以封装成WebElement对象。若发送的cmd命令为例如获取Web的url链接、标题等等时,则无需解析。

获取更多测试干货,请搜索微信公众号:腾讯移动品质中心TMQ!

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏美团技术团队

LsLoader——通用移动端Web App离线化方案

背景 由于JavaScript(以下简称JS)语言的特性,前端作用域拆分一直是前端开发中的首要关卡。从简单的全局变量分配,到RequireJS实现的AMD模块方...

39517
来自专栏一枝花算不算浪漫

Redis的介绍及使用实例.

3429
来自专栏魏琼东

一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-库存查询模块

回顾与说明     前面我就用了大量的篇幅我讲解了“商品入库”模块,在商品入库模块之中,我们介绍 了与之相关的管理信息系统开发中的一个共性场景,以及这个应用场景...

1756
来自专栏杨建荣的学习笔记

使用sysbench压力测试MySQL(二)

昨天有了第一篇的测试之后,仅仅是一个开始。 我接下来做sysbench压测的主要思路是根据现有的配置作出调整,能够持续性的优化和压力测试达到目的,而...

5529
来自专栏北京马哥教育

Linux 进程管理之四大名捕

一、四大名捕 四大名捕,最初出现于温瑞安创作的武侠小说,是朝廷中正义力量诸葛小花的四大徒弟,四人各怀绝技,分别是轻功暗器高手“无情”、内功卓越的高手“铁手”、腿...

2844
来自专栏大数据架构师专家

Linux 进程管理之四大名捕

四大名捕,最初出现于温瑞安创作的武侠小说,是朝廷中正义力量诸葛小花的四大徒弟,四人各怀绝技,分别是轻功暗器高手“无情”、内功卓越的高手“铁手”、腿功惊人的“追命...

722
来自专栏walterlv - 吕毅的博客

异步任务中的重新进入(Reentrancy)

2017-12-05 14:10

371
来自专栏何俊林

一种在Java层实现的守护进程方式

守护进程是一个黑色地带的产物,无论是通过native的方式在linux中fork进程达到,还是在java层通过两个service守护的方式,都是不太友好的做法,...

1866
来自专栏小灰灰

Quick-Task 动态脚本支持框架之任务动态加载

前面几篇博文分别介绍了整个项目的基本架构,使用说明,以及整体框架的设计与实现初稿,接下来则进入更细节的实现篇,将整个工程中核心实现捞出来,从为什么这么设计到最终...

1022
来自专栏java一日一条

java分布式系统开关功能设计(服务升降级)

首先讲一下开关的由来,例如东京在6月18日做店庆促销活动,在交易下单环节,可能需要调用A、B、C三个接口来完成,但是其实A和B是必须的,C只是附加的功能(例如在...

1073

扫码关注云+社区