一种 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 条评论
登录 后参与评论

相关文章

来自专栏沈唁志

PHP新手必须认识的一些建议

1202
来自专栏编程

《PHP扩展及核心》

一、主要内容: 1⃣php扩展的概念和底层实现 2⃣编写一个php扩展的步骤 3⃣php底层,Zend 引擎API的介绍 ,HashTable 原理 二、相关概...

1798
来自专栏jouypub

HTML5 manifest离线缓存

离线访问对基于网络的应用而言越来越重要。虽然所有浏览器都有缓存机制,但它们并不可靠,也不一定总能起到预期的作用。HTML5 使用 ApplicationCach...

743
来自专栏玄魂工作室

CTF实战4 HTTP协议及嗅探抓包

HTTP(Hypertext Transfer Protocol)中文<超文本传输协议>,是一种为分布式,合作式,多媒体信息系统服务,面向应用层的协议,是Int...

612
来自专栏IMWeb前端团队

浅析YSlow-23条规则

本文作者:IMWeb 孙世吉 原文出处:IMWeb社区 未经同意,禁止转载 起因 起初想要去了解如何提高网页加载性能,发现Yahoo发布的一款基于Fi...

1837
来自专栏好好学java的技术栈

「文末赠书」http协议简介看这篇就够了

协议,网络协议的简称,网络协议是通信计算机双方必须共同遵从的一组约定。如怎么样建立连接、怎么样互相识别等。只有遵守这个约定,计算机之间才能相互通信交流。它的三要...

733
来自专栏JetpropelledSnake

Web安全学习笔记之HTTP协议

1072
来自专栏Java进阶

HTTP 通信协议

3428
来自专栏me的随笔

jQuery.ajax 根据不同的Content-Type做出不同的响应

使用H5+ASP.NET General Handler开发项目,使用ajax进行前后端的通讯。有一个场景需求是根据服务器返回的不同数据类型,前端进行不同的响应...

663
来自专栏Google Dart

Dart服务器端 mojito包 原

就像它的名字一样,Mojito主要是糖和其他成分的混合物。 Mojito故意在几个shelf包上非常薄,并专注于构建应用程序的整体体验。

801

扫码关注云+社区