UI自动化测试痛点解决方案

news2024/11/25 10:36:50

前言

UI自动化测试可以快速、准确地执行大量的测试用例,减少人工测试所需的时间和劳动力。能够在短时间内完成多个测试用例的执行,提高测试的效率和速度。但是UI自动化有个最大的痛点。当前端界面发生变化时,往往页面元素定位也会改变,这时就需要投入大量的人力和时间进行修改,导致我们最初引入UI自动化的初衷(节省人力、时间成本,提高测试效率和速度)不能很好的实现。针对这个问题,本篇文章介绍了怎么使用图片定位的方法进行UI自动化测试,抛弃传统的元素定位方式,这样前端页面元素样子没有发生变化,我们就不需要修改维护脚本。如果元素样子发生了变化,我们只需要将以前的元素图片换一张就可以。

介绍

本篇内容主要使用Python、Selenium、PyAutoGUI、OpenCV实现了UI自动化测试,使用图片定位方式。我们将页面元素截取成一个个单独的图片,实际上可能在UI设计后,这些图片都已经由UI设计师切图完成,我们只需要拿到这些切图就可以了。我们将这些元素切图和整体页面进行对比,找出图片在整体界面上的坐标点,然后使用Selenium的ActionChains接口执行页面交互操作就可以了。

实现方式

由于Selenium大家都比较熟悉就不过多介绍了,不熟悉的同学可以参考我之前写的文章《Selenium4.0详细介绍》。

PyAutoGUI是一个Python 第三方库,需要pip install 安装 。它允许我们通过编程方式模拟鼠标和键盘的操作,窗口操作,以及界面的截图匹配。由于它是照搬人的操作,底层没有套牢在Windows系统,所以它可以跨平台。

OOpenCV(开源计算机视觉库)是计算机视觉和机器学习领域广泛应用的一个强大工具,它提供了丰富的API,支持多种编程语言,包括C++、Python、Java等。

安装

pip install pyautogui
pip install opencv-python
# 本人在使用过程中,由于要用到截图,有个报错,需要更新Pillow版本和安装gnome-screenshot,如果没有遇到相关报错,可以忽略下面
pip install Pillow --upgrade
sudo apt install gnome-screenshot

定位图片位置

首先,我们将被测系统的元素图片截图准备好。需要进行的操作是向接口名称输入框中输入‘test’。

系统页面
在这里插入图片描述

元素截图
在这里插入图片描述

定位图片位置

import cv2
import pyautogui


input_img = cv2.imread('input.jpg')
# confidence参数设置了匹配度阈值,范围0到1,值越高要求越精确。
input_img_location = pyautogui.locateOnScreen(input_img, confidence=0.8)
# 获取输入框图片在整体页面的坐标位置,获取的是输入框图片的中心点位置
input_img_x, input_img_y = pyautogui.center(input_img_location)
# input_img_x 370  input_img_y 250

通过上面的方法,我们获取到了输入框的坐标点,下面用Selenium元素定位看一下位置是否正确。

from selenium import webdriver
from selenium.webdriver.common.by import By


input_el = driver.find_element(By.XPATH, '//*[@id="app"]/section/section/div/form/div[1]')
input_el_location = input_el.location
print(input_el_location['x'], input_el_location['y'])
# 220 80

我们发现,两个方法获取的坐标点不一样,由于Selenium获取的是元素的左上角的点,所以我们看一下元素的高和宽计算一下。
在这里插入图片描述

从上图可以看出,元素的宽是296,高是41,通过计算Selenium获取的元素中心点位置为:(368,100.5),x轴坐标没有什么问题,y轴坐标差别有点大。造成这种问题的原因可能是PyAutoGUI获取的是整个电脑屏幕的尺寸,而Selenium获取的可能是浏览器页面的尺寸,我们获取一下他们的整体尺寸对比一下。

import pyautogui
from selenium import webdriver


options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
driver = webdriver.Chrome(options=options)
driver.get('http://172.17.0.1/apitest/#/api?id=79')
pyautogui_size = pyautogui.size()
#获取系统页面尺寸
selenium_size = driver.find_element(By.ID, 'app').size
print(pyautogui_size, selenium_size)
# Size(width=1920, height=1080) {'width': 1920, 'height': 860}

通过上面的对比发现y轴确实不一样,经过查看发现,Selenium获取的是浏览器整个窗口的尺寸,PyAutoGUI获取的是整个电脑屏幕的尺寸,所以我们需要做一个转换

# 我们将获取的元素坐标值,减去Selenium和PyAutoGUI的坐标相差的值,就是实际Selenium操作需要的坐标值,我的y值加70是因为我的操作系统是ubuntu,下面有Dock,高是70.
x = img_x - (pyautogui_x - selenium_x)
y = img_y - (pyautogui_y - selenium_y) + 70

示例

现在我们写一个脚本,使用图片定位的方式,向接口名称输入框输入“test”。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import pyautogui
import cv2


options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
driver = webdriver.Chrome(options=options)
driver.get('http://172.17.0.1/apitest/#/api?id=79')
pyautogui_size = pyautogui.size()
selenium_size = driver.find_element(By.ID, 'app').size
input_img = cv2.imread('img/input.jpg')
input_img_location = pyautogui.locateOnScreen(input_img, confidence=0.8)
input_img_x, input_img_y = pyautogui.center(input_img_location)
x = input_img_x - (pyautogui_size.width - selenium_size['width'])
y = input_img_y - (pyautogui_size.height - selenium_size['height']) + 70
ActionChains(driver).move_by_offset(x, y).click().perform()
ActionChains(driver).send_keys('test').perform()
driver.quit()

最终运行结果

在这里插入图片描述

总结

这样我们就完成了使用图片定位页面元素进行操作。避免了因前端改动,需要重新定位页面元素的痛点。当然这只是个简单的demo,后续项目中使用可能还会遇到其他的问题。包括图形比较复杂的元素图片,这个时候我们可以使用confidence来调整匹配度,当匹配度为1时(最高),图片的一个像素不一致都会导致无法识别出坐标点。所以可以根据自己的实际情况来调整匹配度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2129130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ultralytics实现DeepSort之级联匹配

前面博客中说过,通过Market-1501数据集的训练后可以得到特征提取模型,这个模型最终的输出值为(bs,num_class),但在DeepSort算法应用中的输出结果并非如此,其输出的是特征信息。 特征提取 通过训练后的特征…

通信工程学习:什么是PDF策略决策功能

PDF策略决策功能 PDF策略决策功能(Policy Decision Function, PDF)在通信网络中,特别是在IP多媒体子系统(IMS)中,扮演着至关重要的角色。以下是对PDF策略决策功能的详细解释: 一、定义与功能概…

C语言——课设万能模板、实战项目——学生信息管理系统

本人无偿奉献学生管理系统的所有代码,包括.h头文件和.c文件,要源码私信,或者评论,希望点个关注。可以完整运行。 介绍一下这个系统,该系统包括八个功能: printf("1.录入学生信息\n"); print…

软考中级软件设计师-【计算机系统】必考题汇总

🤹‍♀️潜意识起点:个人主页 🎙座右铭:得之坦然,失之淡然。 💎擅长领域:前端 是的,我需要您的: 🧡点赞❤️关注💙收藏💛 是我持…

中原地产:人力资源数字化创新实践分享

近日,法大大与人力资源智享会(以下简称“智享会”)联合发布了《第七届人力资源共享服务中心研究报告》(点击阅读及下载:最新!《第七届人力资源共享服务中心研究报告》重磅来袭),该报…

2024【华为战报】8月HCIP考试战报!

了解更多往期考试→点 【考试战报】 华为认证 HCIP 8月 微思 | HCIP 考试战报 HCIP 最新开班 厦门面授 全国直播 每月循环开班 点击查看【华为认证 HCIP】 END 微思网络,始于2002年 专业IT认证培训22年,面向全国招生! 微思-主要课程有&a…

【App】

1. 移动App的开发模式 原生开发 - 原生App > Android、IOS、Windows混合开发 - 混合App > React Native、Weex、Flutter React Native 是基于 React 语法开发的一个混合开发框架Weex 是基于 Vue 语法开发的一个混合开发框架Flutter 是 Google 推出来的一款混合开发框架比…

AI大模型全栈工程师课程笔记 - RAG 检索增强生成

文章目录 \1. RAG\2. 构建流程 2.1 文档加载与切分2.2 传统检索引擎2.3 LLM接口封装2.4 构建prompt \3. 向量检索\4. 向量数据库\5. 基于向量检索的RAG\6. 进阶知识 6.1 文本分割粒度6.2 检索后再排序6.3 测试 1. RAG RAG(Retrieval Augmented Generation&#…

计算机网络 --- 计算机网络的分类

一、计算机网络分类 1.1 按分布范围分类 举例:广域网(WAN)、局域网(LAN) 举例:个域网(PAN) 1.2 按传输技术分类 广播式网络――当一台计算机发送数据分组时,广播范围…

xmake与包管理:又一个现代c++构建工具?

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 主要起因是我在逛Reddit帖子时,看到关于一些c构建系统的评价. cmake似乎有些过于复杂,它与vcpkg,conan的包管理之间的"融合"可能在有些时候也显得麻烦. 一些人尝试了我没见过的选项, 所以这里主要试试除了…

推荐一款开源的API开放平台,5分钟就可以搭建企业专属的API开放门户!

在过去的十年中,企业API治理并未受到广泛关注。然而,随着时间的推进,特别是在近几年,企业技术管理者对API治理的重视程度显著提高,开始将API视为企业资产的重要组成部分。API不再仅仅是技术层面的概念,而是…

场外期权合法吗?

今天期权懂带你了解场外期权合法吗?场外期权是指在场外市场进行交易的期权合约,而非在标准化交易所进行交易。这些期权合约通常由交易双方直接协商具体条款,包括到期时间、行权价格和标的资产等。 场外期权主要特点 1.定制化:OT…

一种多态的实现方法

通过 Activator.CreateInstance 以及 继承关系实现 public interface Name{String GetName();}public class Join : Name{public string GetName(){return "Join";}}public class Thomas : Name{public string GetName(){return "Thomas";}}public class …

MongoDB的Map-Reduce操作与聚合管道操作的两个实例相互转换

一、插入集合 comment 的文档的内容 二、题目要求 将集合 comment 中的文档进行聚合操作,即将字段 state为1的文档查询出来,然后按字段 nickname 进行分组,最后计算出每个评论者的评论条数。 三、mapReduce 操作代码 db.comment.mapReduce(// Map函数&…

机器学习(西瓜书)第 7 章 贝叶斯分类器

7.1 贝叶斯决策论 贝叶斯决策论(Bayesian decision theory)是概率框架下实施决策的基本方 法.对分类任务来说,在所有相关概率都已知的理想情形下,贝叶斯决策论考虑 如何基于这些概率和误判损失来选择最优的类别标记.下面我们以多分类任务 为例来解释其基本原理. 贝…

9月12号作业

主要更改的代码 void Widget::read_solt() { QByteArray msg socket->readAll();//接受信息 if(QString::fromLocal8Bit(msg)msg2||msg3QString::fromLocal8Bit(msg)||msg6QString::fromLocal8Bit(msg)) { QListWidgetItem *listItem new QListWidgetItem(QString::fromL…

策略抉择:左右为难,交易方向要如何破局?

交易决策的核心往往围绕着一个关键问题:是采取左侧交易策略还是右侧交易策略?左侧交易,亦称逆向交易,与右侧交易(顺势交易)形成鲜明对比,两者路径迥异,所以让很多交易员不知道该如何…

flac格式怎么转换成mp3?给你介绍8种flac转MP3的方法

flac格式怎么转换成mp3?flac格式以其无损压缩方式闻名,能够保存音频的原始质量,满足高保真音频需求。然而,这种高质量也意味着flac文件通常占用较多的存储空间,这在某些场景下可能不太方便。例如,对于那些希…

增益带宽积和共模抑制比

增益带宽积: 这是运放的开环增益曲线:在10hz以下开环增益不变,但之后,随着频率的增加开环增益逐渐减小,并有一定的函数关系。 增益带宽积 开环增益 * 带宽 不同运放的增益带宽积有所不同。 例如当增益带宽积为10^6…

[Golang] goroutine

[Golang] goroutine 文章目录 [Golang] goroutine并发进程和线程协程 goroutine概述如何使用goroutine 并发 进程和线程 谈到并发,大多都离不开进程和线程,什么是进程、什么是线程? 进程可以这样理解:进程就是运行着的程序&…