【背景介绍】
百度深研MMGame项目组每天提测的apk游戏包数量较大,但由于都是第三方游戏,游戏测试仅包括游戏的简单功能测试和游戏广告测试,人工测试较为繁琐,为了自动化验证游戏功能和广告、提高游戏测试效率,测试项目组在测试中引入开源的Appium自动化测试框架进行自动化测试。但在使用过程中,由于游戏的特殊性,发现很多游戏无法获取到控件、资源ID等内部资源(非原生android代码或使用OpenGL、ActiveX),而目前主要的移动端自动化测试工具基本都是基于获取内部控件元素来进行操作。因此,传统的测试框架和工具无法满足项目组游戏自动化测试的需求。
这种情况下,只能通过点击坐标代替控件操作,而如何自动获取控件坐标就成了能否实现自动化的关键。解决的方法是将开源计算机视觉库OpenCV引入Appium框架,将按钮或控件的截图作为参数输入,在屏幕中通过图像特征识别获取对应控件坐标,调用AppiumAPI实现坐标点击,然后再次调用OpenCV图像识别库,自动判断操作结果,完成自动化测试。
Appium 是一个开源、跨平台的自动化测试工具,可以支持 iOS、Android 和 FirefoxOS 平台。Appium的核心是一个遵守REST设计风格的web 服务器,server监听一个端口,接收由client发送来的command,将其转换成移动设备可以理解的形式,发送给移动设备,移动设备执行完command后把执行结果返回给appiumserver,appiumserver再把执行结果返回给client,其使用Selenium的WebDriver JSON协议,这种架构提供了很好的开放特性,只要某种语言有http客户端的api,就可以通过这个语言编写测试脚本,因此,Appium支持SeleniumWebDriver支持的所有语言,如java、Object-C、JavaScript、Php、Python、Ruby、C#、Clojure、 Perl语言。Appium在iOS部分封装了UIAutomation,Android 4.2以上使用UiAutomator,Android 2.3~4.1使用Instrumentation,也就说Appium同时封装了UiAutomator和Instrumentation。 Appium在不同平台中使用了标准的自动化APIs,所以在跨平台时,不需要重新编译或者修改自己的应用,Appium实现了真正的跨平台自动化测试。
OpenCV的全称 是:Open Source Computer Vision Library(开源计算机视觉库),其可以运行在Linux、Windows和Mac OS操作系统上。OpenCV轻量级而且高效的实现了图像处理 和计算机视觉方面的很多通用算法,算法实现由一系列 C 函数和少量 C++ 类构成 ,同时提供了Python、Ruby、MATLAB等语言的接口。
二、游戏自动化测试框架(Appium与OpenCV结合)
MMGame游戏自动化测试整体框架由Appium构成,Appium作为client与被测APP的桥梁,可以实现连接设备、完成被测APP输入/输出等,OpenCV则为Appium自动化测试提供场景判断、控件获取、结果判断等功能。在对设备进行自动化操作的过程中,关键环节之一就是元素的定位,对于普通应用,Appium提供的API基本能满足测试需求(直接获取控件或资源ID),但是对于游戏(尤其是大型游戏)来说,很多游戏直接使用OpenGL或ActiveX,传统的自动化工具无法通过获取视图元素或资源ID进行元素定位,只能在外部通过坐标点击和屏幕读取进行输入/输出,但是坐标点击适用范围和场景固定,且需要根据特定设备和测试案例进行坐标适配,通用性、可移植性和可维护性较差。
因此,在Appium测试框架的基础上,考虑引入OpenCV进行图像识别与定位,确定控件元素位置,返回坐标,然后由Appium完成对坐标的操作,以此实现游戏的自动化测试与结果验证。OpenCV开源可定制化,兼容多种平台,能够识别经过拉伸和扭曲的图像,适用于测试2D/3D游戏,非常适合引入Appium进行游戏自动化测试,更进一步,可以依此实现游戏云端远程并行测试,极大的扩展测试规模和测试服务,减少测试人力,加快测试效率。除此之外,图像处理功能模块独立且通用性极强,与平台、设备无关,也可以应用到其他任何需要图像识别的产品进行功能扩展。鉴于此,OpenCV的引入,不仅不会影响Appium的跨平台通用性,且解决了Appium无法获取普通应用部分元素和游戏中无法获取内部资源的问题,极大的扩展了Appium的功能。
在具体游戏测试中,OpenCV实现以下3个功能:
• 确定当前在游戏的哪个阶段;
• 根据提供的按钮、控件截图,确定其坐标;
• 判断游戏表现是否符合预期。
Appium+OpenCV整体框架如下图1所示:
图1 Appium+OpenCV整体框架
Appium测试框架的使用网上已经很多,在此不再做多说明,本文主要介绍OpenCV在Appium中的使用。
三、自动测试整体结构和实现原理
Appium中使用OpenCV进行游戏自动化测试的大致流程如下:
首先收集相关控件的截图;
然后通过Appium获取屏幕当前截图,将提供的截图和当前截图作为输入,使用OpenCV(3.0及以上版本)中集成的Akaze特征识别算法进行特征识别,确定截图在屏幕中的坐标;
再通过Appium API实现坐标操作,并获取操作后屏幕截图;
再次进行图像处理,判断点击后的效果是否符合预期,给出测试结果,完成测试。
完整工程结构如下:
图2 Appium+OpenCV整体结构
这其中最为核心的是Akaze特征识别算法。Kaze是 Pablo F. Alcantarilla, Adrien Bartoli 和 Andrew J. Davison 2012年在ECCV2012[ECCV是计算机视觉领域最顶尖的三个会议(CVPR、 ECCV, ICCV)之一,每两年一次]中提出来的一种比 SIFT、SURF(OpenCV 2.4.9版本中实现的图像特征检测算法)更稳定、性能更好的特征检测算法。
KAZE特征检测是在图像域中进行非线性扩散处理的过程。KAZE算法的作者提出采用 加性算子分裂算法(Additive Operator Splitting, AOS)来进行非线性扩散滤波,可以采用任意步长来构造稳定的非线性尺度空间。
KAZE特征的检测步骤大致如下:
1)首先通过AOS算法和可变传导扩散方法来构造非线性尺度空间。
2)检测感兴趣特征点,这些特征点是在非线性尺度空间上经过尺度归一化后的Hessian矩阵行列式中的局部极大值(3×3邻域)。
3)计算特征点的主方向,并且基于一阶微分图像提取具有尺度和旋转不变性的描述向量。
Kaze算法的作者在2013年的BMVC(British Machine Vision Conference)会议上,又对Kaze算法做了改进,引入了一个最新的称为快速显示扩散的(Fast Explicit Diffusion,FED)数学框架去进行特征发现和描述,FED方案构建非线性尺度空间的速度比其他离散化方案的速度都要快,此外,FED方案非常易于实现,也比AOS方案更为精确,作者提出在椎体框架中嵌入FED可以显著加快非线性尺度空间的特征发现,并将这种改进的Kaze算法称之为 AcceleratedKAZE ,即为Akaze。
作者基于OpenCV实现了Akaze算法的代码,在作者项目主页(http://www.robesafe.com/personal /pablo.alcantarilla/kaze.html)可以下载到完整的实现源代码,具体使用中可以下载OpenCV 3.0及以上版本直接调用Akaze算法类,或者将下载的Akaze代码添加进工程来使用。
图2中的Img文件夹中保存了预先传入的截图(queryImg文件夹)和获取到的屏幕截图(sceneImg文件夹),以及使用特征识别算法匹配到的结果图片(matchImg文件夹),具体如下图3所示:
图3 工程图片目录结构
图2中imgProcess.py基于OpenCV提供的底层图像处理接口,封装了一系列自动化测试中所需要的特征识别、结果图绘制、获取坐标等接口,以获取截图坐标函数为例,其大致实现过程如下:
• 使用特征检测算法Akaze分别计算控件截图和屏幕截图的特征值和描述向量;
• 将两张图的特征值进行匹配;
• 过滤匹配成功的坐标对;
• 根据过滤后的坐标对计算转换矩阵;
• 获取控件截图的4个顶点坐标,使用转换矩阵运算,映射至屏幕坐标;
• 根据屏幕坐标计算中心点坐标并返回。
大致代码如下图4所示:
图4 imgProcess.py代码结构
图2中Appium_OpenCV_TestCase.py是执行具体测试逻辑的测试用例,代码具有简单易写,结构简单,逻辑清晰的优点。Appium测试用例有固定的模板,不同的是,在测试case代码中,使用OpenCV进行图像匹配、坐标获取、结果确认等,取代了传统的通过获取视图元素或资源ID实现操作,大致代码如下图5所示:
图5 测试用例Appium_OpenCV_TestCase.py代码结构
四、使用效果
1、功能测试
为了展示使用效果,以实际工作中的一款被测游戏APP为例,使用以上实现的框架和图像匹配功能,进行简单的基于Appium+OpenCV实现的功能自动化测试演示。
首先,我们根据需要测试的功能逻辑,收集相关截图,如下图6所示:
图6 相关控件截图
运行测试脚本中,会自动获取特定时刻的屏幕截图,如下图7所示:
图7 屏幕截图
然后将屏幕截图与传入的按钮截图进行图像匹配,部分匹配结果如下图8所示:
图8 图像识别结果(绿色方框区域即为识别到的控件区域)
上面绿色方框就是通过图像匹配,在屏幕截图中找到的对应控件的位置,可以看出,除了第一张稍有偏差,其他控件基本是100%匹配,而且第一张虽有一定偏 差,但是匹配结果的中心坐标点(即绿色方框的中心点)仍在控件的可点击范围内,也是可点击成功的。至于为何Star按钮会出现匹配误差,这与传入的按钮截 图有关。项目组在实际使用中总结了以下3条经验:
• 截取最精确的源图片(最小化原则),提高匹配精确度
将需要匹配的控件图片拆分成较小的、唯一的元素。
缺点:图片小,获取到的特征点少,容易匹配失败,匹配成功率低
优点:匹配精确度高
• 放大源图片,提高匹配成功率
将需要匹配的图片适当放大,提高匹配成功率,但匹配误差增大,精确度降低,此时可以根据实际经验值对阈值进行调整来保证匹配准确度。
缺点:特征值增多,容易发生误匹配,精确度降低;需要根据实际情况获取经验值,修改匹配阈值。
优点:匹配成功率较高
• 图片截取使用屏幕原生分辨率
2、游戏简单功能测试与广告自动验证
项目组日常提测的第三方游戏数量较大,每天有几十甚至上百款apk包提测,目前,项目组测试团队已经将游戏测试结果上传Mars(测试支持平台),但是需要人工去查看图片确认广告是否正常、游戏安装和启动是否正常,考虑到测试逻辑较为固定且繁琐,比较合适引入图像识别,项目组测试团队引入封装好的图像处理模块,使用图像识别自动验证广告是否弹出成功,自动判断游戏是否崩溃、黑屏、闪退等,然后自动在Mars平台标记测试结果,无需再去进行人工检查,具体步骤如下图9所示:
图9 破解游戏自动结果检测
使用图像匹配进行广告验证和游戏场景识别的代码如下图10所示:
图10 游戏场景匹配
广告匹配结果图如下图11所示(弹出的广告与传入的广告截图完全一致):
图11 广告场景匹配
如果弹出的广告与传入的广告截图不一致,由于有其他相同的特征点,也是可以匹配成功的,只是需要调整匹配阈值,确保不同广告出现时不被判断为广告展现失败,结果如下图12所示:
图12 广告场景匹配
但实际测试过程中会出现很多其他情况,例如如果广告被其他广告或者窗口覆盖,则会匹配失败(匹配成功特征值对数目太小),如下图13所示:
图13 广告场景匹配失败
因此,可以使用源图片截取的最小化原则,对场景进行二次识别,例如这里可以再次对广告的关闭按钮进行匹配,如下图14所示:
图14 广告场景二次确认
崩溃匹配的结果如下图15所示:
图15 崩溃场景匹配
但是也会出现一些误匹配,如下图16所示:
因此,在具体测试过程中,如果出现某些场景图像识别错误率较高,需要对正确匹配和错误匹配情况下的特征值匹配对数目进行统计分析,确定一个经验值,以此作为判断是否匹配成功的阈值,也可以调整Akaze算法的内部函数系数,来保证识别的准确度在可接受范围内。
自动检验完毕后,根据检验结果在Mars上自动标记测试结果,测试人员只需在测试脚本运行完毕后去Mars平台查看测试结果,然后发送测试报告即可,如下图17所示。
图17 自动标记检测结果
为了检验引入图像识别进行自动测试与人工测试结果的出入,测试团队将游戏100款游戏的自动测试结果和人工测试结果进行了对比,在测试的全部游戏中,人工检查判断为不通过,但是自动检查判断为通过(这种情况是最为严重的)的有4款,占比大概为4%,主要原因是有少量的游戏需要弹框提示下载新版本安装包或者 弹框提示应用未授权,由于这种情况出现较少,测试逻辑中并没有包含对这些场景的识别,因此判定为通过。
引入图像识别进行自动检验后,省去了第三方游戏自动化测试流程中最为关键的一个需要人工干预的环节,打通了整个自动化测试流程,目前除了自动发送测试报告邮件外,其他都已经实现,自动测试流程如下图18所示:
图18 游戏自动化测试流程
五、对比与总结
以上就是基于Appium框架,在其中引入OpenCV进行游戏自动化测试的实现与应用,其最主要就是解决了游戏APP或其他普通应用在无法获取其内部资源进行元素定位的情况下,如何不依赖内部资源实现自动化测试的问题,且图像处理模块开源、独立,可以应用于其他平台和场景,具有较好的可移植性和可扩展性。
下面针对Appium+OpenCV与当前主流的测试框架、工具的实现和特点做一个简要的对比与总结。
1、Appium+OpenCV与当前主流测试框架、工具对比
目前,Android基于UI层面的自动化测试工具,都可以理解为是基于Android控件层面的,涉及Widgets和WebView两大类。其主流的测试方法主要有以下两种:
一种是通过Android提供的各种服务,来获取当前窗口的视图信息。然后,在当前视图内查找目标控件,并根据该控件属性信息计算出该控件中心点的坐标,进而构造出一个AndroidInput事件来实现对应用的自动化测试。其主要特点是:测试代码和被测应用各自运行在各自的进程内,相互独立,其代表有Uiautomator。
另一种则是基于Instrumentation,Instrumentation是早期Google提供的Android自动化测试工具类,可以模拟按键按下、抬起、屏幕点击、滚动等事件。Instrumentation是通过将主程序和测试程序运行在同一个进程来实现这些功能,可以把Instrumentation看成一个类似Activity或者Service并且不带界面的组件,在程序运行期间监控主程序。通过把测试代码和应用代码,确切地说是测试APK和被测APK,运行在同一个进程中,通过Java反射机制,来获取当前窗口所有视图,并根据该视图查找到目标控件的属性信息,并计算出目标控件中心点坐标。然后,利用Instrument内部接口,实现点击操作,其代表有Robotium。
这两种方法有一个共同的特点,就是其实现自动化测试依赖于被测应用的代码或者内部资源,如果无法获取到内部控件或者资源ID,就无法进行元素定位,也就无法实现自动化操作。而基于Appium引入OpenCV,可以实现不依赖于应用内部资源就可以进行自动化功能测试,极大的扩展了传统测试框架和工具的功能,且具有良好的平台兼容性、可扩展性和可移植性。
且 Appium同时封装了UIAutomation和Instrumentation,所以Appium拥有目前使用以上这两种方法实现的主流框架的所有优 点:支持跨App测试,支持Native App、Hybird App、Web App测试,还支持多种语言来编写你的测试脚本,在跨平台时,不需要重新编译或者修改自己的应用等等。
目前主流的移动端(Android、IOS)自动化测试框架、工具有以下这些,详见表1:
表1 移动端主流自动化测试框架、工具
下面针对目前业界主流的一些测试移动端测试框架和工具与Appium+OpenCV的优缺点做一个比较,详见下表2:
表2 Appium+OpenCV与主流移动端测试工具对比
2、总结
综合来说,Appium+OpenCV主要的优缺点如下:
1)优点:
• 无需获取游戏内部资源,直接进行黑盒自动化测试;
• Appium、OpenCV均是开源、跨平台,具有很好的适用性和功能扩展性;
• OpenCV能够识别经过拉伸和扭曲的图像,满足大型3D游戏测试需求;
• 使用简单,测试case代码易写;
• 图像识别模块可独立迁移;
2)缺点:
• 纯黑盒测试方案,仅限于基本功能测试;
• 仅限于对逻辑相对固定的操作进行测试;
• 对于界面内容及UI变化的游戏,脚本维护成本高;
• 图像识别有一定误差。
总的来说,由于Appium+OpenCV主要基于Appium实现,所以具有Appium本身的优点,而Appium本身同时封装了UIAutomation和Instrumentation,所以Appium拥有以上这几个框架的所有优点,而引入OpenCV,弥补了Appium在无法获取被测应用内部资源的情况下不能进行自动化测试的缺点,同时提供了在其他情况下需要进行场景自动识别的功能。