前端项目中的绝大多数代码是GUI界面,如何测试GUI一直是比较头疼的问题,主流的UI自动化(QTP、Selenium等)也大都缺少对界面的验证,这主要和前端项目迭代性高、维护成本大相关。GUI界面自动化目前在业界也没什么较好的解决方案。 一个标准的互联网应用产品的前端部分,粗略估计大概有20%的业务基础代码比较稳定,比如通用组件、通用算法和数据模块等,可以针对这些建立复杂一些的API和GUI测试用例来保证质量。剩下80%的部分不是很稳定,每天都在迭代,针对他们维护case的成本非常高。目前业界中号称做了自动化测试的项目,也大多是在做那稳定的20%。 二八原则在此得以体现。目前业内大部分测试团队还是靠堆人来完成简单的界面测试,可以说,GUI界面测试的成本非常高。那是否可以略过这80%?显然是否定的,事实往往遵循墨菲定律:任何事都没有表面看起来那么简单;会出错的事总会出错。可是即使耗费了人力进去,常令人沮丧的是,仍有隐蔽且无法轻易测出的BUG。 初衷 如何解决UI界面测试的困局?从0出发,测试人员是如何测试界面的,首先要有个参照物,可能是设计图,也可能是上一版本的产品;看 ⊙_⊙ 、肉眼比对,俗称 “大家来找茬”。 几个页面还可以玩玩,但是,如果是全站点,本身页面多,还包括很多弹窗,再好玩也不好玩了。。。 那是否可以把这一整套流程进行自动化呢?初步设定了以下方案,差Coding了 (? ??_??)? 实际上这个想法并非独树一帜,国外已有团队使用,早在2012年,Twitter分享的开发流程,其中有一个环节是页面对比监控,利用了一个叫pdiff的工具,每次提交代码,会自动对比页面之间的差异然后提醒测试人员注意回归。 解决方案——页面差异检测 网站页面截图 很多UI自动化测试工具/框架均支持页面截图,实现起来不难。之前开发的 Selenium + Python UI自动化测试框架,可支持截屏;且支持各种测试场景,如点击后出现弹窗或一系列操作等;也支持多浏览器(IE、Chrome、FireFox)。
以上为一个很简单的用例示例,即访问百度页面并截图,访问本地下载的百度页面截图(做了一些元素变更) 针对截屏,部分页面可能有如下问题: 1、需滚动条滚屏截图 2、一些自动播放的插件,如幻灯片自动播放等截图会不一样 对于问题一,建议直接加JS代码操作滚动条操作后分段截图;至于问题二,插件可设置为静止(测试服务器),或者让差异存在,检测出之后人工排除该问题即可。 若是静态页面,且不需要登录等授权操作,一些多浏览器截图服务可被使用,如阿里FTS前端测试服务: http://fts.aliyun.com/index.htm 图像比对 图像比对本身可作为一个大课题,这边化大为小,直接使用Python的Image模块来进行简单的图像比对(程序保证截屏的图片大小一致)。 以下图片来自上述自动跑UI自动化用例的自动截图,下文作为示例图来分析如何图像比对(有看出哪不同了么):
这边的图片对比代码原理:获取图像每一像素点,若RGB相同,定为相同,不同的定为不同,相同的像素/总像素即为相似比。 实际上大部分页面相似度较高,若仅对截取的页面进行比对,示例相似度为 0.995369926989。那么问题来了,判定相似率必定才是相同,这合理么?虽然后续又跑了好几次截图,与图一对比都是。。。 先略过判定的问题,再来看下图三,初看和图一没什么不一样,但执行代码后得出的相似率为0.977268178495。程序不会骗你,肯定有不一样。所以,再仔细看看 = — =
看出来了么?Tida~ 是二维码图片。来看下我对本地页面做了什么,实际仅仅改了一个数字,即下图样式,原 “qrcode-item-1” 改成了 “qrcode-item-2” 而已。
上述示例展示了较隐蔽且会被人眼忽视的盲区,且若为真实Bug,影响较大。通过页面比对,可以轻易检测出类似Bug。那么问题又来了,检测出不同后,如何标识出不同的范围?程序代码固然可以捞出一大堆不一样的元素点坐标,并以不同颜色标识,但看上去很恶心(试过。。真的很恶心),如果能像找茬一样框出不同可好。于是想到了裁切对比并标识的想法 ???? 顺便也可解决大定判定的问题,来具体看下如何操作。下图为执行的代码(图一对比图二),函数方法说明下(对应方法的代码需调整,待调整完后放出), calc_similar_by_path() 进行两张图片的相似度计算; cropImg() 进行图片裁切,如下,裁切成了4块(如有需要,怎么裁都行),下图文件夹中为裁切完成的图片(实际运用无需保存图片,仅作示例方便查看);下面几个数字分别为对应小图对比的结果,可见仅一块非1,且比之前对比出的0.995小多了,是不同点所在。 1.0 1.0 0.949275005378 1.0
我们可以先检测大图的相似度,若为1,完全相同即可略过;若非1,再做裁切的图片检测并可根据检测出的哪块框哪块。之后是记录的工程了,简单写了个对比图片页面,展示如下:
基于上述的页面差异对比监控,可以建立一个任务系统,把应用的所有页面url监控起来(包含主要操作后的截图),每次版本迭代提交代码后,系统进行页面差异对比,报告出哪些页面存在差异、具体的页面差异又是什么。 适用测试场景 回归界面测试:新版页面 VS 旧版页面 项目界面测试:Mockup VS 实际测试页面 兼容性测试:如chrome VS 其他各种浏览器 页面差异监控的目的是方便的通知人肉回归范围,这并非测试方案,而是一种辅助测试的手段。 优化及衍生 selenium webdriver仍需要启动真实的浏览器并操作,在执行性能上有一定的劣势。可考虑使用无界面浏览器测试并截图,如 PhantomJS + Selenium,优势是执行效率大大提升,劣势在于PhantomJS不是真实浏览器,且无法做多浏览器截图。 Phantom JS是一个服务器端的 JavaScript API 的 WebKit。其支持各种Web标准: DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG。由于脚本好像是一个Web浏览器上运行的一样,标准的DOM脚本和CSS选择器可以很好的工作。这使得PhantomJS适合支持各种 页面自动化任务 。 基于像素点的图片差异,误报率可能比较高,可衍生考虑做基于DOM树的diff,优势是可以减少误报,且定位至元素;劣势是该比对技术要求较高(要求对DOM树操作了解较深),可参考 前端工程——测试篇 (文中提到的项目两年前已经停更,运行起来貌似有点问题)