一开始接触到视觉测试的时候还是去京东参加沙龙的时候,第一次接触到了这个概念。可能是命运的捉弄吧,去完回来第二天,我们公司就上马了一个商城的项目(这个商城的项目做得我痛不欲生 )一测就是快 4 个月,然后各种基于商城的业务如雨后春笋般层出不穷,导致我需要去看太多太多的图片,经常会漏掉一些很小的但又很重要的地方,外加开发更改细微布局也不会提前告知我们,导致第一遍看过去有错,第二遍的时候这个错找不到了。所以在开发人员的一再逼迫下,我决定去试试视觉测试解决下看看,结果收效显著,现在我只用去 report 就可以了,不过现在还是有些弊端的(我会在结尾处说明)。好的我们就不多介绍了,我们先上截图。
首先,我们来主要讲下思路
思路很简单的,截图的工具我 PC 端用的是 selenium,移动端用的是 appium。
根据这个流程,大概的操作步骤是这个样的在,第一步使用 selenium 或者 appium 进行截图,将第一次的截图定位母图,存放在 bitmaps_reference 目录下,然后更改下存放图片的路径,再次运行截图,本次截取的是测试的图片,我们将图片存放在 bitmaps_test 目录下,然后触发运行图像对比模块,进行图像比较,并判断两张图片是否不同,如果不同的话生成两张图片不同的位置的图片,存放在 diff_image 目录下,然后将所有数据进行收集,收集后生成一份 html_report 报告,这个报告会存放在 html_report 目录下。到此结束了,我们只用去看报告就知道,母图与测试图片哪里不一致(显示不同图片的功能还需要改善,正在改善中.....),在报告中添加了一些筛选,搜索,和拉杆功能,方便去观察两张图片的不一致性。下面是一些操作的截图。
第一张目录存放位置
第二张测试图存放位置
第三张对比图存放位置
第四张报告存放位置
报告样式图
报告功能图(1)
功能图(2)
功能图(3)
至此截图部分就展示完毕了。
下面我们上一些代码,看看功能实现(小白一个,代码较丑,大神勿喷,妈咪妈咪哄)
上面的代码就是一个简单的比较,同 pillow 包里面的 difference 方法进行图片的比较,然后生成一张对比图片,如下图所示:
我们可以看到黑黢黢的一片,一点不好看,而且受到多像素的限制,这个方法在对比底色跨度的时候经常会出现,一片马赛克,如下图:
不知道的话还以为是空白的,但是结果还是好的,是比较出了不同,但是不能满足我们追求完美的决心,所以我暂时在报告中加上了滑竿进行一下细致的对比。
当然我也在改进那个黑黢黢的图片尽量做到,在原图上标注出不同图片的位置,在这里必须说明一下,简单的同底色图片已经可以做到我说的这些(我会在下面进行简单的展示,基于还没有彻底完善代码,在一些值的计算上还存在一些误差和问题,我就不把全部代码放出来丢人现眼了),我先讲下思路,其实就是通过对生成的对比图片进行二值转换,将全部的 x 轴和 y 轴的每个坐标上的值进行输出,输出之后进行重组在一个坐标系内,在这个重组坐标系内会出现一些区域为(1,1)的坐标,而这些坐标就是我们图像上的不同部分,通过这个方法找到全部的不同位置,比产出全部的矩形区域坐标,当然我们会发现在产生的矩形区域坐标中存在一些无用区域坐标,我们在这里用像素管道对比的方法将这些无用区域坐标删除,删除后就剩下我们可用的坐标了,在进行标注,就可以实现我想要的效果了。
代码如下:
改进后的截图和之前的图片对比
这样就基本上满足了我们的需要,可以看到不同而且不是黑黢黢的了,下面是新产生的报告截图
这样看上去是不是清爽多了。
讲了这么多,我的初衷就是为了减少人工点点点对的操作,所以在我们完成这些操作之后,必须去想想,这个方法的一些不足核问题:
问题一:对一些特定区域将无法进行区分,比如说广告。举个例子,我在一开始测试自己写的代码时候,用淘宝进行了测试,发现每次截取的广告图片都不一样,导致代码进行识别后全部判定为失败,只能通过人工去进行识别。所以针对与这个的改进思路有两个,第一个是通过 selenium 或 appium 将广告所在位置进行隐藏在截图,第二种就是通过 CSS 进行对比,在脚本中隐藏广告部分。
问题二:一些人为改动,举个例子:一开始我们存在母图中的图片的 title 字体颜色为黑色,但是由于客户喜好,将 title 颜色改为了红色。当遇到这种情况的时候,识别系统也会识别到那里的不同,从而导致判定失败。没有办法只能又去人工识别判断下。解决办法也有:通过跟开发沟通产生一份白名单,在判断的时候去识别下该图片是不是在白名单中,从而忽略这种情况造成的影响。
问题三:如果一个页面不分页,显示会很长很长(手机中常见),用 selenium 截图时,他只能截取到一部分图片不能去全部截取,就会导致对比不全,从而可能漏掉一些 bug。改进思路:第一种是通过拼接将全部图片拼起来再去识别;方法二:是通过 request 把整个网页都扣下来,在用 selenium 去截取,这样就可以截取一张整图;第三种方法:通过 CSS 将图片拉扯下来,截取全部进行比较。
问题 4:一些功能原件,导致截图对比失败,举个例子,我们在测试手机端的时候,进场会遇到一个滚动条,这个滚动条往下滑动后,每次停留在的位置都不一样,导致是识别的时候,就将原本没有问题的图片判定为失败了。改进思路:方法一:用 CSS 隐藏滚动条在截图;方法二:通过 selenium 操作 js 来实现不显示滚动条,在截图。
我现在遇到的就是这些问题啦。希望大家遇到问题后可以给我反馈,我也及时去修改和改进,在我将那些遗留的错误值和 bug 彻底修改后,我会开源这可东西的。
(哎呀说了这么多)顺便把下一步说一下吧,我计划在 appium 的测试上将思寒老师(我是思寒老师的学生哦,顺便帮他宣传下)@seveniruby (思寒) 的那个 appium 自动遍历的嫁接上,直接生成截图直接去对比,从而生成报告,就可以省去一些看截图的痛苦。在 PC 端去嫁接 debugtalk (九毫)@debugtalk (九毫) 大神的一个遍历系统,从而省去写脚本一些不便。
最后的最后给大家推荐一些 css 回归的已经算比较成熟的框架,webdrivecss,PhantomCSS,Gemini。当然特别推荐一位谷歌大神写的对比图片 dpxdt--这个可是 python 做的哦(只不过用的是 2.7 写的,我用 3.6 所以就用不了 )