web自动遍历&视觉对比工具开发过程记录

前言

完全自动的业务测试可以说是自动化测试的终极梦想,不需要任何的自动化代码,就可以实现对业务逻辑的自动测试,极大的释放了人力;但仅称作是梦想也是有原因的,形态各异,日趋复杂的业务逻辑,基本让全自动沦为奢望,即便是加上最新的ai技术,也无法搞定所有的业务场景;

但是,先退一步,完成半个小目标,总归还是可以的。

背景

BG主要业务线的实现载体为web或者h5,各业务线更新上线频繁,实现完全的自动化脚本覆盖维护成本过高;因此,需要一种工具,可以在低人力成本的前提下,通过设立基准线,利用工具同时遍历基准和新版本的页面,通过图像对比的方式,自动得出差异;再加以人工检视,最快程度的完成新版本回归工作。

目标

  • 低代码化使用,可自动遍历指定网页
  • 页面覆盖率40%以上
  • 结果自动进行图像差异比对

实现过程

测试流程

整体测试流程如下图(引自图像对比在UI测试中的实践-技术篇)

10956783-503751ac09ca9133.png

通过总入口开启基准和对比网页的自动遍历,并在每步骤后截图,当全部遍历完毕时,将基准和对比版本的截图上传到对比引擎,并最终进行展示。

关键技术点

滑块验证码的自动登录实现

由于BG大部分项目均存在滑动验证码才能登录,过往的自动化脚本是采用cookies注入规避该项,但并非所有项目都存在该方式可供使用;因此若需大规模能否自动化过滑块验证码是较为重要的技术关键点。

本次开发主要使用了目标检测模型yolov5,通过不断爬取验证码图片,并进行人工标注训练滑块位置,将训练好的模型通过服务化的方式对外提供接口,最终实现上传验证码图片后,可自动识别缺口位置,再通过自动化技术进行滑动处理。

需要说明是,一般而言,selenium技术栈中,滑动使用的是win的键鼠api,但实践下来不建议这里使用,是因为,为了保证截图的长度可以截取到全部网页列表,因此,使用了无头浏览器的形式启动web;而该方式无法使用win的键鼠api对滑块进行操作。

实际操作里,这块使用了js注入实现了滑块滑动,js代码如下:

    js_str = """
    btn=document.getElementsByClassName("geetest_slice_bg")[0];
    mousedown = document.createEvent("MouseEvents");
    rect = btn.getBoundingClientRect();
    x = rect.x||rect.left;
    y = rect.y||rect.top;
    
    //点击滑块
    mousedown.initMouseEvent("mousedown",true,true,window,0,
            x, y, x, y,false,false,false,false,0,null);
    btn.dispatchEvent(mousedown);
    var mousemove = document.createEvent("MouseEvents");
    var move_x = {move_x};
    mousemove.initMouseEvent("mousemove",true,true,window,0,
                x+move_x, y, x+move_x, y,false,false,false,false,0,null);
    btn.dispatchEvent(mousemove);
    var mouseup = document.createEvent("MouseEvents");
    mouseup.initMouseEvent("mouseup",true,true,window,0,x+move_x, y, x+move_x, y,false,false,false,false,0,null);
    btn.dispatchEvent(mouseup);""".format(move_x=offset) """

网页自动遍历关键技术实现

js抓取元素xpath
抓取流程

该部分主要流程图如下:

temp.png

元素过滤规则

web页面上各项元素很多,许多元素的点击事件都是一层一层往下传下来的,因此,如果不加筛查每个元素都点,会造成很多冗余点击;此外,业务上也有很多元素不想进行点击或者需要更改点击顺序;这里做了几层过滤规则。

1、 手形标志过滤
一般而言,鼠标悬浮到元素上方是手形标志时,通常代表该元素是设计上可进行交互的,因此,需要首先过滤掉不具备手形样式的元素(getComputedStyle(nodes[i]).cursor === 'pointer')。

2、 黑区域控制
很多时候,业务上某些区域下的元素都不想进行点击(如富文本框、不可操作数据等),因此,通过cssname指定元素区域后,可过滤掉在该区域下的所有元素不参与xpath列表生成。

3、 cssname黑名单
除了区域控制外,也提供了基于cssname的黑名单,只要元素样式包含该css,则将其过滤。

4、 targetname黑名单
除了css样式黑名单外,还可以指定targetname如style、script等无法点击的target类型。

5、 优先级控制
通过指定的cssname进行排序,凡是在该cssname区域下的所有元素,优先级都会被排到后面。

短xpath构建

通常而言,市面上一般使用长xpath,也就是full xpath进行xpath构建,这种全路径的xpath优点是可识别性更高,很难出现不同页面相同的xpath;但缺点是路径过长,不够稳定,路径节点的中的元素只要一个变化,就可能导致认为出现了一个新元素;

因此,在通常的长xpath构建规则基础上,这里加以改良,通过对比全局dom,增加了诸如text、css、id等特征点的识别,典型的短xpath类似:

//*[@class='el-icon-switch-button']/parent::*、 //*[text()='修改结果']
主遍历逻辑

该部分主要流程图如下:

temp2.png

查丢策略

抓取元素后,其实遍历策略仅仅是操作进行挨个点击,递归直到元素列表为空而已;重点在于,经过点击操作后,很可能会进行页面的跳转,或者发生新元素对旧元素的遮盖,从而导致原先元素列表内的元素无法被点击到,也就是丢元素。

这里采用了多种策略,在元素丢失的情况下进行查找,尽量避免丢元素的发生。

1、 步骤回溯
在点击元素时,每次新产生元素,都会为新产生的元素进行映射表记录,将点击了XX元素导致新产生XXX元素列表通过键值对的形式记录下来;在丢失某个元素时,先查找这个元素对应的映射元素是什么(也就是点击什么元素导致出现的这个元素),如果当前页有这个映射元素,就点击这个映射元素,再查找这个丢失的元素;如果当前页没有这个映射元素,就去找这个映射元素又是点击什么元素出现的(也就是这个映射元素的映射元素是什么),找到后重复以上流程,直到可以按照记录的步骤将丢失的元素点出来。

2、位置回溯
每次生成新的元素列表后,都会先记录该元素列表内,所有元素的位置信息;一旦元素丢失无法找到,就会尝试在当前页查找这个元素的位置上,有没有元素,如果有,位置信息是否和原元素的位置信息一致,如果一致,就代表找到了。

3、url回溯
很多时候,点击元素会跳转到新的url上,在当前页是不可能找到的;因此,在生成元素列表时,还会记录一份元素和url的映射关系,当元素丢失时,如果这个元素的映射url和当前的url不一致,则会拉回记录的映射url,再进行元素查找。

图片对比引擎mico

在遍历和截图生成完毕后,需要上传一份基准版本和一份对比版本的截图到图片对比引擎进行对比;这里直接使用的开源的图片对比引擎mico,详见mico的说明:https://arxman.com/micoo/

最终效果

通过各项黑名单和优先级的配置后,经过实际的项目验证,可到90%的页面覆盖率。

你可能感兴趣的:(web自动遍历&视觉对比工具开发过程记录)