UI自动化测试中公认最佳的设计模式-POM
一、概念
什么是POM?
POM是PageObjectModule(页面对象模式)的缩写,其目的是为了Web UI测试创建对象库。在这种模式下,应用涉及的每一个页面应该定义为一个单独的类。类中应该包含此页面上的页面元素对象和处理这些元素对象所需要的方法等。将流程所关联的页面作为对象,将对象串联起来,形成一个个不同的流程,POM是业内公认最佳的设计模式。
POM的优点:
(1)PO提供了页面元素操作和业务流程相分离的模式,可以使测试的代码结构比之前清晰,可读性强。
(2)更方便地复用对象和方法。
(3)对象库是独立于测试用例的、统一的对象库,可以通过集成不同的工具类来达到不同的测试目的。比如集成UnitTest可以用来做单元测试、自动化/功能测试,同时也可以集成JBehave/Cucumber等来做验收测试。
(4)使得整体自动化测试的优点变得更容易一些,如果有某个页面的元素需要变更,那么就可以直接更改封装好的页面元素类即可,而不用更改调用它的其他测试类/代码。这样整个的代码维护成本也会缩减。
PO的核心就是分层思想,把同属于一个页面的元素都放在一个页面类中。
以上概念内容来源于某书籍
二、简要结构设计
-
逻辑代码:基类,实现所有工具函数封装,类似于关键字驱动设计模式;
-
页面对象代码:基于系统页面,通过调用工具函数来实现业务的操作,生成对应的页面对象;
-
测试代码:基于测试需要,组件页面对象,实现核心流程的自动化,执行测试用例;
-
测试数据:为测试用例的执行提供所需要的测试数据。
三、POM完整框架
-
Base层:定义项目需要的基础方法,特别是一些基础操作,如元素click操作、sendkeys操作,调用JavaScript脚本的方法和其他一些与基本浏览器相关的操作。
-
Common层:包含处理Excel文件的方法,获取项目路径、测试系统URL的信息和框架执行相关日志功能的实现方法。
-
Data层:存放测试数据,在这里可以维护测试数据,这样存放是为了让项目的可维护性强、整体的条理性强。测试数据有时是自动化测试的驱动因素,因此对Data的管理和维护就显的特别重要。
-
Logs层:存放项目在运行过程中产生的日志文件。
-
PageObject层:这里是PO的核心层,该层不但涉及代码技术,还涉及对项目业务的分析,进而对项目的页面进行分析。
-
Reports层:存放项目执行过程中产生的测试报告文件,测试报告是对测试结果的总结。
-
TestCase层:管理测试用例和执行测试,相当于测试的总入口。
-
config.ini:整个项目需要用到的配置项。
四、项目实战
以百度搜索为例
- 我们首先新建一个简单的项目结构:base、data、page_object、cases,如下图所示:
2. 在base包下新建一个base_page.py文件,在base_page.py文件下新建一个BasePage
类作为基类,提供各个常用的已封装好的函数,便于后续的页面对象类进行调用。selenium中常用的函数:元素定位、输入、点击、访问URL、等待、关闭等。代码如下:
-
'''
-
基类:提供各个常用的已封装好的函数,便于后续的页面对象类进行调用。
-
selenium中常用的函数:元素定位、输入、点击、访问URL、等待、关闭
-
'''
-
from time import sleep
-
from selenium import webdriver
-
class BasePage:
-
driver = webdriver.Chrome()
-
# 访问URL
-
def visit(self, url):
-
self.driver.get(url)
-
# 元素定位
-
def locator(self, loc):
-
return self.driver.find_element(*loc)
-
# 输入
-
def input(self, loc, txt):
-
self.locator(loc).send_keys(txt)
-
# 点击
-
def click(self, loc):
-
self.locator(loc).click()
-
# 等待
-
def wait(self, time):
-
sleep(time)
-
# 关闭
-
def close(self):
-
self.driver.quit()
- 在page_object包下新建一个search_page.py文件,在该文件下新建一个
SearchPage
类继承BasePage
类,调用基础类中的方法实现页面操作,生成对应的页面对象。代码如下: -
'''
-
百度查询页面,搜索功能
-
'''
-
from selenium.webdriver.common.by import By
-
from base.base_page import BasePage
-
from selenium import webdriver
-
class SearchPage(BasePage):
-
url = 'http://www.baidu.com'
-
# 定位百度输入框
-
search_input = (By.NAME, 'wd')
-
# 定位百度一下按钮
-
search_button = (By.ID, 'su')
-
# 封装实现业务流程的函数
-
def search(self, txt):
-
self.visit(self.url)
-
self.wait(2)
-
self.input(self.search_input, txt)
-
self.wait(2)
-
self.click(self.search_button)
- 在cases包下新建一个testcase.py文件作为测试类,实现在百度中分别搜索selenium、python,代码如下:
-
'''
-
测试类
-
'''
-
import unittest
-
from page_object.search_page import SearchPage
-
from selenium import webdriver
-
class Case(unittest.TestCase):
-
def test_search1(self):
-
driver = webdriver.Chrome()
-
txt = 'selenium'
-
SearchPage(driver).search(txt)
-
def test_search2(self):
-
driver = webdriver.Chrome()
-
txt = 'python'
-
SearchPage(driver).search(txt)
-
if __name__ == '__main__':
-
unittest.main()
运行以上代码发现,因为创建了两次webdriver,所以每运行一次代码都会打开一个Chrome浏览器,同时,代码中也存在冗余。优化方案:可以增加@classmethod
作为前置条件和后置条件,搜索的条件也可以采用数据驱动的方式完成,提高代码的可读性与维护性。
在data包下新建一个searchTXT.yaml文件,存放搜索的内容如下:
优化之后代码如下:
-
'''
-
测试类
-
'''
-
import unittest
-
from page_object.search_page import SearchPage
-
from selenium import webdriver
-
import ddt
-
@ddt.ddt()
-
class Case(unittest.TestCase):
-
@classmethod
-
def setUpClass(cls) -> None:
-
cls.driver = webdriver.Chrome()
-
cls.se = SearchPage(cls.driver)
-
@classmethod
-
def tearDownClass(cls) -> None:
-
cls.driver.quit()
-
@ddt.file_data('../data/searchTXT.yaml')
-
def test_search(self, txt):
-
self.se.search(txt)
-
if __name__ == '__main__':
-
unittest.main()
运行以上代码,发现测试用例执行了四次,分别搜索了selenium、python、java、php,如此实现了数据驱动,同时也在一个浏览器中完成了操作。
五、后记
以上简单的实现了POM的设计模式,完成了基类、页面对象层、数据层、测试层的代码编写,若读者有兴趣,可以完成报告层、日志层等内容的编写,最终实现完整的框架。
感谢每一个认真阅读我文章的人!!!
作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
相关文章:
UI自动化测试中公认最佳的设计模式-POM
一、概念 什么是POM? POM是PageObjectModule(页面对象模式)的缩写,其目的是为了Web UI测试创建对象库。在这种模式下,应用涉及的每一个页面应该定义为一个单独的类。类中应该包含此页面上的页面元素对象和处理这些元…...
数字图像处理(2):Verilog基础语法
(1)Verilog常见数据类型: reg型、wire型、integer型、parameter型 (2)Verilog 常见进制:二进制(b或B)、十进制(d或D)、八进制(o或O)、…...
大公司如何实现打印机共享的?如何对打印机进行管控或者工号登录后进行打印?异地打印机共享的如何实现可以帮助用户在不同地理位置使用同一台打印机完成打印任务?
大公司如何实现打印机共享的?如何对打印机进行管控或者工号登录后进行打印?异地打印机共享的如何实现可以帮助用户在不同地理位置使用同一台打印机完成打印任务? 如果在局域网内,可以不需要进行二次开发,通过对打印机进…...
解决前端页面报错:Not allowed to load local resource
在前后端分离项目中,在前端页面里使用file://的绝对路径访问本地图片,在加载图片的 时候会报出Not allowed to load local resource 的错误。 这是因为浏览器出于安全因素,禁止通过绝对路径访问图片,需要通过虚拟路径进行访问。 …...
Qt 实现网络数据报文大小端数据的收发
1.大小端数据简介 大小端(Endianness)是计算机体系结构的一个术语,它描述了多字节数据在内存中的存储顺序。以下是大小端的定义和它们的特点: 大端(Big-Endian) 在大端模式中,一个字的最高有效…...
2024年11月21日Github流行趋势
项目名称:twenty 项目维护者:charlesBochet, lucasbordeau, Weiko, FelixMalfait, bosiraphael项目介绍:正在构建一个由社区支持的现代化Salesforce替代品。项目star数:21,798项目fork数:2,347 项目名称:p…...
Java的方法、基本和引用数据类型
个人的黑马程序员java笔记 目录 方法 例:方法定义和调用 方法的重载 对于byte, short, int, long类型 方法的内存 基本数据类型 引用数据类型 方法的值的传递的内存原理 方法 方法(method)是程序中最小的执行单元格式 方法定义&a…...
Spark分布式计算中Shuffle Read 和 Shuffle Write的职责和区别
在 Spark 的分布式计算中,Shuffle Read 和 Shuffle Write 是两个与数据重新分区和分发相关的重要阶段。它们的主要职责和区别如下: 1. Shuffle Write Shuffle Write 发生在上游的任务执行阶段,其作用是: 分区数据准备࿱…...
【成品文章+四小问代码更新】2024亚太杯国际赛B题基于有限差分格式的空调形状优化模型
这里仅展示部分内容,完整内容获取在文末! 基于有限差分格式的空调形状优化模型 摘 要 随着科技进步,多功能环境调节设备成为市场趋势,集成了空调、加湿器和空气 净化器功能的三合一设备能提供更舒适健康的室内环境。我们需要分析…...
实验三:构建园区网(静态路由)
目录 一、实验简介 二、实验目的 三、实验需求 四、实验拓扑 五、实验任务及要求 1、任务 1:完成网络部署 2、任务 2:设计全网 IP 地址 3、任务 3:实现全网各主机之间的互访 六、实验步骤 1、在 eNSP 中部署网络 2、配置各主机 IP …...
MySQL 三大日志详解
在 MySQL 数据库中,binlog(二进制日志)、redo log(重做日志)和 undo log(回滚日志)起着至关重要的作用。它们共同保障了数据库的高可用性、数据一致性和事务的可靠性。下面将对这三大日志进行详…...
vscode使用ssh配置docker容器环境
1 创建容器,并映射主机和容器的指定ssh服务端口 2 进入容器 docker exec -it <容器ID> /bin/bash 3在容器中安装ssh服务 apt-get update apt-get install openssh-server 接着修改ssh文件信息,将容器的10008端口暴露出来允许root用户使用ssh登录 vim /…...
Python设计模式详解之10 —— 外观模式
引言 Facade设计模式(外观模式)是一种软件设计模式,它提供了一个统一的接口来访问子系统中的一组接口。Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。当一个系统的内部实现非常复杂,或者需要与…...
[服务器] 腾讯云服务器免费体验,成功部署网站
文章目录 概要整体架构流程概要 腾讯云服务器免费体验一个月。 整体架构流程 腾讯云服务器体验一个月, 选择预装 CentOS 7.5 首要最重要的是: 添加阿里云镜像。 不然国外源速度慢, 且容易失败。 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/li…...
低速接口项目之串口Uart开发(四)——UART串口实现FPGA内部AXILITE寄存器的读写控制
本节目录 一、设计背景 二、设计思路 三、逻辑设计框架 四、仿真验证 五、上板验证 六、往期文章链接本节内容 一、设计背景 通常,芯片手册或者IP都会提供一系列的用户寄存器以及相关的定义,用于软件开发人员进行控制底层硬件来调试,或封装…...
【Datawhale组队学习】模型减肥秘籍:模型压缩技术4——神经网络架构搜索
神经网络架构搜索是通过自动化方法来设计神经网络架构的一种技术,与传统手工设计网络结构相比,NAS能够在大量可能的架构中进行搜索,找到最优的神经网络架构,从而减少人工调参和设计的时间。学习这章时,重点在于理解NAS…...
用el-scrollbar实现滚动条,拖动滚动条可以滚动,但是通过鼠标滑轮却无效
问题: 用elementplus实现的滚动条的页面中,滑动滚动条可以滚动,但是通过鼠标滑轮却无效,鼠标没有问题。 解决: 在开发者工具中, 元素->时间监听器中发现当我移除网页中祖先元素的滚动事件,该…...
windows下,用CMake编译qt项目,出现错误By not providing “FindQt5.cmake“...
开发环境:windows10 qt5.14, 编译器msvc2017x64,CMake3.30; 现象: CMakeList文件里,如有find_package(Qt5 COMPONENTS Widgets REQUIRED) target_link_libraries(dis_lib PRIVATE Qt5::Widgets) 用CMak…...
windows实现VNC连接ubuntu22.04服务器
最近弄了一个700块钱的mini主机,刷了ubuntu22.04系统,然后想要在笔记本上通过VNC连接,这样就有了一个linux的开发环境。最后实现的过程为: 安装vnc服务器 安装 VNC 服务器软件: sudo apt update sudo apt install t…...
SQL注入--联合注入--理论
什么是SQL注入? SQL注入(SQL Injection)是一种常见的Web安全漏洞。 形成的主要原因是web应用程序在接收相关数据参数时未做好过滤,将其直接带入到数据库中查询,导致攻击者可以拼接执行构造的SQL语句,从而获…...
LaTeX 利用注销 ccmap 宏包实现降重功能
在中文LaTeX中,ccmap 宏包的主要作用是支持复制和粘贴时正确处理中文字符的编码。它的功能对于生成的PDF文档尤其有用,使得PDF中的中文字符在被复制到其他地方时能够以正确的编码显示,而不是乱码或其他不正确的字符。 以下是ccmap的详细功能…...
NVR接入录像回放平台EasyCVR视频融合平台加油站监控应用场景与实际功能
在现代社会中,加油站作为重要的能源供应点,面临着安全监管与风险管理的双重挑战。为应对这些问题,安防监控平台EasyCVR推出了一套全面的加油站监控方案。该方案结合了智能分析网关V4的先进识别技术和EasyCVR视频监控平台的强大监控功能&#…...
经验笔记:远端仓库和本地仓库之间的连接(以Gitee为例)
经验笔记:远端仓库和本地仓库之间的连接 方法一:先创建远端仓库,再克隆到本地 创建远端仓库 登录到你的Git托管平台(如Gitee、GitHub、GitLab、Bitbucket等)。点击“New Repository”或类似按钮,创建一个新…...
趋势洞察|AI 能否带动裸金属 K8s 强势崛起?
随着容器技术的不断成熟,不少企业在开展私有化容器平台建设时,首要考虑的问题就是容器的部署环境——是采用虚拟机还是物理机运行容器?在往期“虚拟化 vs. 裸金属*”系列文章中,我们分别对比了容器部署在虚拟化平台和物理机上的架…...
数据科学与SQL:组距分组分析 | 区间分布问题
目录 0 问题描述 1 数据准备 2 问题分析 3 小结 0 问题描述 绝对值分布分析也可以理解为组距分组分析。对于某个指标而言,一个记录对应的指标值的绝对值,肯定落在所有指标值的绝对值的最小值和最大值构成的区间内,根据一定的算法&#x…...
Cesium的ClearCommand的流程
ClearCommand是在每帧渲染前可以将显存的一些状态置为初始值,就如同把擦黑板。当然也包括在绘制过程中擦掉部分的数据,就如同画家在开始绘制的时候会画导览线(如透视线),轮廓出来后这些导览线就会被擦除。 我画了一个…...
DBeaver错误:Public Key Retrieval is not allowed
问题原因 MySQL 8.0 默认使用 caching_sha2_password 认证插件,并要求客户端能够使用 RSA 公钥进行加密操作。如果客户端无法正确处理 RSA 公钥检索,就会触发这个错误。 解决方案 右键编辑连接-连接设置-属性驱动-修改allowPublicKeyRetrieval属性的值…...
slice介绍slice查看器
Android Jetpack架构组件(十)之Slices - 阅读清单 - 腾讯云开发者社区-腾讯云 slice 查看器apk 用adb intall 安装 Releases android/user-interface-samples GitHubMultiple samples showing the best practices in the user interface on Android. - Releases android/u…...
Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf)(很详细)
我试了似乎不支持vue3 原文链接:Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf)-阿里云开发者社区...
缓存工具类编写
缓存工具类编写 一般操作 在外面日常开发中,经常会有为了减少数据库压力,而将数据保存到缓存中并设置一个过期时间的操作。日常代码如下: Autowired private RedisTemplate<String, String> redisTemplate;public Object queryDataW…...
基于Java Springboot高校会议室预订管理系统
一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…...
redis-击穿、穿透、雪崩
击穿、穿透、雪崩经常听人说吧? 那他到底是啥呢?无非就是在有缓存层的情况下,对各种绕过缓存层从而直接落到了DB上的情况进行的分类。 概念性的东西大概如下,我是记不住,后期具体使用与规避这些问题才是大事ÿ…...
javascrip页面交互
元素的三大系列 offset系列 offset初相识 offset系列属性 作用 element.offsetParent 返回作为该元素带有定位的父级元素,如果父级没有定位,则返回body element.offsetTop 返回元素相对于有定位父元素上方的偏移量 element.offsetLeft 返回元素…...
PAL(Program-Aided Language Model)
PAL(Program-Aided Language Model)是一种结合生成式语言模型(如 GPT)和程序执行能力的技术框架。它的核心思想是通过让语言模型生成代码或程序来解决复杂任务,程序执行的结果反过来增强语言模型的输出准确性和逻辑性。…...
Altium Designer学习笔记 6-10 异性元件库创建_原理图绘制
基于Altium Designer 23学习版,四层板智能小车PCB 更多AD学习笔记:Altium Designer学习笔记 1-5 工程创建_元件库创建 目录 6、光耦及二极管元件库模型创建 7、元件库模型的调用 二、原理图绘制及编译检查 8、元件的放置 9、器件的复制及对齐 10、…...
Qt-多元素控件
Qt中的多元素控件 Qt提供的多元素控件有: 这里的多元素控件都是两两一对的。 xxWidget和xxView的一个比较简单的理解就是: xxView是更底层的实现, xxWidget是基于xxView封装来的。 可以说,xxView使用起来比较麻烦,但…...
网络安全-web架构-nginx配置
1. nginx访问: 访问的是index.html, 访问ip访问的资源就是在/usr/share/nginx/html中; 当nginx不认识,浏览器认识的话,浏览器会自动渲染。 当nginx认识,浏览器不认识的话,浏览器会把它加载成…...
CPU性能优化--微操作
x86 架构处理器吧复杂的CISC指令转为简单的RISC微操作。这样做最大的优势是微操作可以乱序执行,一条简单的相加指令--比如ADD,EAX, EBX,只产生一个微操作,而很多复杂指令--比如ADD, EAX 可能会产生两个微操作,一个将数…...
开源许可协议
何同学推动了开源协议的认识,功不可没,第一次对开源有了清晰的认识,最宽松的MIT开源协议 源自OSC开源社区:何同学使用开源软件“翻车”,都别吵了!扯什么违反MIT...
React核心功能详解(一)
React是一个流行的JavaScript库,用于构建用户界面。其高级核心功能涵盖了多个方面,以下是对这些功能的详解: 一、组件化与模块化 组件化开发:React提倡将用户界面拆分成多个独立的组件,每个组件负责管理自己的状态和…...
在vue中,根据后端接口返回的文件流实现word文件弹窗预览
需求 弹窗预览word文件,因浏览器无法直接根据blob路径直接预览word文件,所以需要利用插件实现。 解决方案 利用docx-preview实现word文件弹窗预览,以node版本16.21.3和docx-preview版本0.1.8为例 具体实现步骤 1、安装docx-preview插件 …...
基于Spring Boot的同城宠物照看系统的设计与实现
摘 要 科学技术日新月异,人们的生活都发生了翻天覆地的变化,同城宠物照看系统当然也不例外。过去的信息管理都使用传统的方式实行,既花费了时间,又浪费了精力。在信息如此发达的今天,我们可以通过网络这个媒介&#x…...
Python操作neo4j库py2neo使用之py2neo 删除及事务相关操作(三)
Python操作neo4j库py2neo使用之py2neo 删除及事务相关操作(三) py2neo 删除 1、连接数据库 from py2neo import Graph graph Graph("bolt://xx.xx.xx.xx:7687", auth(user, pwd), nameneo4j)2、删除节点 # 删除单个节点 node graph.node…...
二分基本实现
模板 一般题目看到,最大,最小时优先考虑二分 //将区间分为 [l,mid-1] int erfen1(int l,int r) {while(l<r){int mid(lr1)/2;if(check())lmid;elsermid-1;}return l; }//将区间分为 [mid1,r] int erfen2(int l,int r) {while(l<r){int mid(lr)/2…...
数据结构中的随机抽取和顺序存取
在数据结构领域,随机存取与顺序存取是两种基本的存储模式。这两种模式在很大程度上决定了数据的组织与访问方式,从而对数据处理效率和存储空间的利用效果产生重要影响。本文将进一步探讨这两种存储模式的特点及其差异。 随机存取 随机存取,…...
大数据新视界 -- 大数据大厂之 Impala 性能优化:跨数据中心环境下的挑战与对策(上)(27 / 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
GPT中转站技术架构
本文介绍阿波罗AI中转站(https://api.ablai.top/)的技术架构,该中转API的技术架构采用了分布式架构、智能调度和API中转等技术,确保了全球范围内的高效访问和稳定运行。以下是对该技术架构的详细分析: 分布式架构 分…...
忽然就卷起来的AI Coding 赛道
忽然就卷起来的AI Coding 赛道 原创 松子 松子聊数据 2024年11月22日 17:03 2023年,大模型的爆发让整个行业经历了一场“拼尽一切”的竞赛——拼算力、拼参数、拼语料,再到今天开始拼智能体。 每一步都是技术的跃迁,也让市场竞争愈发白热化…...
十大网络安全事件
一、私有云平台遭攻击,美国数千家公司工资难以发放 1月,专门提供劳动力与人力资本管理解决方案的美国克罗诺斯(Kronos)公司私有云平台遭勒索软件攻击,事件造成的混乱在数百万人中蔓延。 克罗诺斯母公司UKG集团…...
1+X应急响应(网络)病毒与木马的处置:
病毒与木马的处置: 病毒与木马的简介: 病毒和木马的排查与恢复:...