曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补

文章目录

一、Selenium的缺点分析

常用的Web自动化测试方法往往都是基于元素定位的方式来进行的,比如热门的selenium、appium都是基于这种方式的。

但随着reactvue的普及,以及elementantd等组件库的出现,,通过元素定位的方式就显得有心无力了!

为什么这样说呢?我们举一个简单的例子来说明:

下面是通过antd组件库来实现的一个小Demo,页面有两个个按钮:【添加用户】、【修改用户】:

曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


它们会打开编辑用户资料的弹窗的弹窗,弹窗里他们都有两个相同的【确认】按钮。
曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


我们知道,通过元素地址来定位元素的第一要点就是这个元素有唯一标识,当然有些小伙伴会说,直接通过Xpath路径定位不用唯一标识也能定位到!
这里先不做解释,我们一步一步来分析,告诉你为什么不建议使这么做!
如下图所示,这两个确定按钮的元素地址无论标签、文本信息、还是class都是完全一样的,因为都来源antd组件库的同一组件。所以它们没有任何区别!


曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


正因为它们没有唯一的标识,所以如果想通过idclass、甚至是xpathcontains方式来定位,selenium识别不了到底是哪一个按钮,就会失效!

当然,也正如上文说到的,通过xpath路径的定位方式也可以定位成功,就算没有唯一标识也行。

但会带来什么样的影响呢?还是举个例子告诉你:

我们先打开添加用户的弹窗,获取【确定】按钮的xpath地址:

/html/body/div[2]/div/div[2]/div/div[2]/div[3]/button[2]

然后再打开修改用户弹窗,获取它的【确定】按钮的xpath地址:

/html/body/div[3]/div/div[2]/div/div[2]/div[3]/button[2]

可以明显的发现:它们的div层级不一样,一个是div[3]一个是div[2],其他都是一样的。这样能够执行成功,也能区分出两个按钮!

但是,如果你先打开的是【修改用户】的弹窗,那它的【确定】按钮所在的div层级就不是[3]了,会变成[2]!!
这样就与【添加用户】弹窗的【确定】产生了冲突,他们的元素层级都在div[2]了,当你再次执行时就会出现问题!在我们编写自动化测试脚本的时候,不可能一番风顺,总会因为各种原因出现一些问题,慢慢修改解决,一次次重跑才能解决!但正因为这样的操作,以及元素路径地址的不确定性,会大大加大我们的工作量!

而且必须按照预定的顺序执行,对于上述的场景中,我们的执行顺序必须是先打开【新建用户】的弹窗,再打开【修改用户】的弹窗,如果顺序反了,就会定位失败!
另外,前端调整页面,哪怕微调,也可能导致相关模块的整个UI用例全部需要重写!

一点维护性都没有,还谈什么高效?


在网上也有小伙伴提出了类似的问题:


曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


它们的解决方案是让开发加上id来解决。但实际上开发是不会情愿去为了方便你做自动化测试来加id的,因为会增加它的工作量。即便开发愿意加入id,我们的工作量依然很大!
首先,上述的两个【确定】按钮的样式和标签等信息都是一样的。但你还是需要写两个元素地址来区分他们,如果一个弹窗嵌套的比较深,还有二级弹窗、三级弹窗,那你就需要写多个【确定】元素地址,这依然很麻烦!

在我实际的项目中,有一个嵌套多层的弹窗,它的确认按钮就有7个!
曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


那有没有只用一个元素地址,也不用让开发加唯一标识就能解决这些问题呢?

肯定是有的,不然我也不会写这篇文章了!


二、解决方案

1. 讲解与演示

我们可以使用图像识别来定位它,比如网易团队开源的airtest,类似于上述弹窗嵌套有多个【确定】按钮的情况,我们只需要截取一张【确定】按钮的图片,就能解决无数重复的确定按钮的定位了!


这是我通过截图-图像识别的执行效果:
曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


两个【确定】按钮完全共用的是一张图片


2. 实践教学

现在跟着我一起从0开始利用airtest写一个简单的图像识别测试脚本吧

需求

编写一个程序,它会通过图像识别执行点击百度的【新闻】,然后点击【互联网】这两步操作


具体步骤

1.先安装airtest

pip install airtest -i https://pypi.tuna.tsinghua.edu.cn/simple


2.创建一个项目,并输入如下代码:

from airtest.core.api import *

news_path = 'news.png'
internet_path = 'internet.png'
connect_device('Windows:///')
ST.CVSTRATEGY = ["surf", "tpl"]
ST.FIND_TIMEOUT = 2
touch(Template(news_path))
touch(Template(internet_path))


3.先打开百度截取【新闻】图片,再点击新闻,截取【互联网】图片:


曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


截取的图片如下,命令为news.png并保存到代码所在目录


曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


截取的图片如下,命令为internet.png并保存到代码所在目录*


曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


4.检查目录文件命名是否与代码中一致


曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


5.让浏览器保持百度访问


曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


6.执行代码然后马上切换回浏览器,执行效果如下:


曲鸟全栈UI自动化教学(一):重复元素如何定位区分?Selenium的缺点让图像识别来弥补


完全脱离了元素地址的方案进行自动化测试,并且无论上Web还是App,甚至PC应用都能够兼容!


三、依然存在的问题

在使用中可能会发现,分辨率不同,截取的图片就用不了!如果被测机器的分辨率都不相同,那是不是就得需要多套图片呢?

其实airtest针对此问题也有一些解决方案:

  1. 更改识别算法 (本人亲测,效果不好!!)
  2. 通过重写官方代码来实现适配分辨率的图片压缩方法
  3. 更改识别相似度阈值

另外airtest也有不可忽视的缺点:

  1. 被测对象必须保持可见(无法隐藏浏览器进行)
  2. 界面有相同元素时无法定位

所以airtestselenium相结合才是目前最好的选择!

本专栏会专门针对 airtest 和 selenium 相结合进行自动化测试的知识分享
从0到1教学,让你能够独立搭建商业级自动化测试框架!


上一篇:Airtest 环境搭建之JDK1.8下载安装&配置&完全卸载


下一篇:这款开源测试神器,圆了我玩游戏不用动手的梦想