前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一种 Android 端 Web 多进程情况下支持 Web 自动化测试的方法

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

原创
作者头像
腾讯移动品质中心TMQ
修改2017-07-12 11:23:49
2.1K0
修改2017-07-12 11:23:49
举报

作者:陈航特

团队:腾讯移动品质中心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页面。

[1499826765111_4577_1499826891801.png]
[1499826765111_4577_1499826891801.png]

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

[1499826795625_5056_1499826922311.png]
[1499826795625_5056_1499826922311.png]
[1499826817838_4192_1499826944509.png]
[1499826817838_4192_1499826944509.png]
[1499826828346_5175_1499826954976.png]
[1499826828346_5175_1499826954976.png]

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

[1499826839462_3124_1499826966103.png]
[1499826839462_3124_1499826966103.png]

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

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

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

[1499826853719_7987_1499826980412.png]
[1499826853719_7987_1499826980412.png]
[1499826867813_5280_1499826994500.png]
[1499826867813_5280_1499826994500.png]

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

[1499826880849_6730_1499827007483.png]
[1499826880849_6730_1499827007483.png]

以下是Robotium中的实现:

[1499827049094_4318_1499827175854.png]
[1499827049094_4318_1499827175854.png]

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

[1499827061450_2654_1499827188146.png]
[1499827061450_2654_1499827188146.png]

简要原理图如下:

[1499827073208_4523_1499827199858.png]
[1499827073208_4523_1499827199858.png]

二、Web多进程后的问题

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

[1499827086106_2292_1499827212754.png]
[1499827086106_2292_1499827212754.png]

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

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的代码,对安装包影响小、安全风险可控。方案示例图如下:

[1499827102534_9192_1499827229218.png]
[1499827102534_9192_1499827229218.png]

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

[1499827118720_1767_1499827245411.png]
[1499827118720_1767_1499827245411.png]

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!

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Android端Web自动化原理简介
  • 二、Web多进程后的问题
  • 三、Web多进程后的支持Web自动化测试方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档