PO设计模式是selenium自动化测试中最佳的设计模式之一
Page Object Model:PO设计模式是selenium自动化测试中最佳的设计模式之一,主要体现在对界面交互细节的封装,也就是在实际测试中只关注业务流程就OK了传统的设计中,在新增测试用例之后,代码会有以下几个问题:1.易读性差:一连串的find element会使代码显得杂乱无章2.可扩展性不好:用例孤立,无法扩展3.可复用性差:无公共方法,很难复用4.可维护性差:一旦元素变化,需要维护修改大量测试用例 因此考虑到优化: PO模式是一种自动化测试设计模式,讲页面定位和业务操作分开,也就是把对象的定位和测试脚本分开,从而提供可维护性。
首先抽象封装一个BasePage类,这个基类拥有一些指向Webdriver实例的属性,然后每一个Page继承基类BasePage,可以通过driver管理每一个Page中的元素,而且在Page中将这些操作封装为一个一个的方法。TestCase继承unittest里面的TestCase类,并且依赖page类,进行组织测试步骤的工作。
这样做的好处,就是有元素变化,只需要维护每一个Page就行了,测试步骤变化,只需要维护TestCase即可
PO各个核心要素的介绍:
BasePage:
class BasePage(object):def __init__(self,driver):self.driver = driverpass
Page:
from SeleniumProject.PO.BasePage import BasePage
class LoginBase(BasePage):# 定位元素,括号中是通过find_element来获取元素的属性uname = ()pwd = ()def set_uname(self,uname):name =self.driver.find_element(*LoginBase.uname)name.send_keys("用户名")def set_pwd(self,pwd):password = self.driver.find_element(*LoginBase.pwd)password.send_keys("密码")pass
TestCase:
from unittest import TestCase
import unittest
from selenium import webdriver
class Test_Login(TestCase):def setUp(self):self.driver = webdriver.Chrome()self.driver.get("https://cn.bing.com/")# 测试步骤def test_Login(self):self.driver.get(self.base_url)passdef tearDown(self):self.driver.quit()if __name__ == "__main__":unittest.main()
下面举一个简单的例子来看一下PO模式:
业务要求就是,用Chrome浏览器,在https://cn.bing.com/中搜索“墨菲特”,然后点击搜索按钮,再关闭浏览器
基类BasePage类:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECclass BasePage(object):"""BasePage封装所有页面的公有方法,例如url、driver、find_element"""# 构造函数里面的参数就是类的所有参数def __init__(self,selenuime_driver,base_url):self.driver = selenuime_driverself.url = base_url# 定义一个私有方法,其他类不能调用该方法def _open(self,url):self.driver.get(url)self.driver.maximize_window()# 定义open()方法,调用_open()方法def open(self):self._open(self.base_url)# 重写find_element()方法,参数为任意数量的(带*的参数)# 此方法是为了保证元素是可见的def find_emelemt(self,*loc):try:# 保证元素可见WebDriverWait(self.driver,10).until(EC.visibility_of_all_elements_located(loc))return self.driver.find_element(*loc)except:print("页面中没有%s %" % (self.loc))# 定义script()方法,用于执行JS脚本,比方上上传文件啥的def script(self,src):self.driver.excute_script(src)# 定义页面跳转方法,比方说有的页面有frame嵌套def switch_frame(self,loc):return self.driver.switch_to_frame(loc)# 重新定义send_keys()方法,为了保证搜索按钮是否存在,还有有的输入框中默认有值,要清空def send_keys(self,loc,value,clear_first=True,click_first=True):try:# getattr方法相当于实现了self.locloc = getattr(self,"_%s"%loc)# 是否存在搜索按钮if click_first:self.find_element(*loc).click()# 清空搜索框中的值,并输入需要搜索的值if clear_first:self.find_emelemt(*loc).clear()self.find_emelemt(*loc).send_keys(value)except:print("页面上未找到%s元素"%(self.loc))
Page类:
from selenium.webdriver.common.by import By
from SeleniumProject.PO.BasePage import BasePageclass SearchPage(BasePage):# 定位元素search_loc = (By.NAME,"q") #搜索框btn_loc = (By.NAME,"go") #搜索按钮# 重写父类的open()方法def open(self):self._open(self.base_url)def search_content(self,content):# 调用父类的find_emelemt,然后将本类的参数传入content1 = self.find_emelemt(*self.search_loc)content1.send_keys(content)def btn_click(self):btn1 = self.find_emelemt(*self.btn_loc)btn1.click()
TestCase类:
from unittest import TestCase
import unittest
from selenium import webdriver
from time import sleep
from SeleniumProject.PO.Search import SearchPage
class CaseRun(TestCase):def setUp(self):self.driver = webdriver.Chrome()sleep(3)self.url = "https://cn.bing.com/"sleep(3)self.content = "墨菲特"# 测试步骤def test_search(self):bing_page = SearchPage(self.driver,self.url)bing_page.open()sleep(3)bing_page.search_content(self.content)sleep(3)bing_page.btn_click()sleep(3)def tearDown(self):self.driver.quit()if __name__ == "__main__":unittest.main()
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
软件测试面试小程序
被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!
涵盖以下这些面试题板块:
1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux
6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
相关文章:
PO设计模式是selenium自动化测试中最佳的设计模式之一
Page Object Model:PO设计模式是selenium自动化测试中最佳的设计模式之一,主要体现在对界面交互细节的封装,也就是在实际测试中只关注业务流程就OK了传统的设计中,在新增测试用例之后,代码会有以下几个问题:…...
yolov8使用C++推理的流程及注意事项
1.下载yolov8项目源码GitHub - ultralytics/ultralytics: NEW - YOLOv8 🚀 in PyTorch > ONNX > OpenVINO > CoreML > TFLite 2.下载opencvReleases - OpenCV,建议版本>4.7.0,选择下载源码, windows版本由于使用的编译器与我们所使用的m…...
深度思考计算机网络面经之二
HTTP2和1.1的区别 HTTP 2.0 和 HTTP 1.1 相比有哪些优势呢? HTTP1.1的队头阻塞问题 服务器必须按照请求接收的顺序来响应,为什么 是因为传统的1.1中没有特定字段来区分一个请求属于哪个,只能按照请求的物理顺序返回, HTTP2解…...
老年人跌倒智能识别算法 opencv
老年人跌倒智能识别算法通过opencvpython深度学习算法框架模型,老年人跌倒智能识别算法能够及时发现老年人跌倒情况,提供快速的援助和救援措施,保障老年人的安全。Python是一种由Guido van Rossum开发的通用编程语言,它很快就变得…...
ros2官方文档(基于humble版本)学习笔记
ros2官方文档(基于humble版本)学习笔记(一) 一、安装ROS2二、按教程学习1.CLI 工具配置环境 由于市面上专门讲ROS2开发的书籍不多,近期看完了《ROS机器人开发实践》其中大部分内容还是基于ROS1写的,涉及top…...
可拖动表格
支持行拖动,列拖动 插件:sortablejs UI: elementUI <template><div><hr style"margin: 30px 0;"><div><!-- 数据里面要有主键id, 否则拖拽异常 --><h2 style"margin-bottom: 30px&qu…...
C++语法基础
这里写目录标题 基础语法第一个程序变量常量的定义关键字标识符命名 (变量命名)sizeof的使用实型(浮点型)字符型转义字符字符串的定义 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 基础语法 第一个程序 …...
Windi CSS和Tailwind CSS以及UnoCSS
最近合作在写一个vue3ts的项目,看到其他人用了一种写法,我觉得很奇怪,之前没见过,他是这样写的 <div class"news flex-1 h-40px flex"></div>我不理解的是为什么这样写就会让这个div的高度就是40px,好多代码…...
c++ opencv将彩色图像按连通域区分
要将彩色图像按连通域区分,您可以使用 OpenCV 中的 cv::connectedComponents 函数。 下面是一个简单的示例代码,说明如何使用 cv::connectedComponents 函数来检测并标记图像中的连通域: #include <opencv2/opencv.hpp> #include <…...
〖程序员的自我修养 - 认知剖析篇⑩〗- 学习编程的高效率方法
人之所以会觉得迷茫,本质上是欠缺对自己的一个控制力、识别庞杂信息、去伪存真的独立思考与认知能力。 说明:该文属于 程序员的自我修养 专栏,购买任意白宝书体系化专栏可加入易编程社区,早鸟价订阅模式除外。福利:加入社区的小伙伴们,除了可以获取博主所有付费专栏的阅读…...
前端基础1——HTML标记语言
文章目录 一、基本了解二、HTML常用标签2.1 文本格式化标签2.2 列表标签2.3 超链接标签2.4 图片标签2.5 表格标签2.6 表单标签2.6.1 提交表单2.6.2 下拉表单2.6.3 按钮标签 2.7 布局标签 一、基本了解 网页组成(index.html页面): HTML标记语言…...
2.1: Dubbo的基本应用-负载均衡,集群容错,服务降级
负载均衡 官网地址: http://dubbo.apache.org/zh/docs/v2.7/user/examples/loadbalance/ 如果在消费端和服务端都配置了负载均衡策略, 以消费端为准。 这其中比较难理解的就是最少活跃调用数是如何进行统计的? 讲道理, 最少活跃数…...
正则常见问题及解决方案
使用正则处理问题的基本思路。有一些方法比较固定,比如将问题分解成多个小问题,每个小问题见招拆招:某个位置上可能有多个字符的话,就⽤字符组。某个位置上有多个字符串的话,就⽤多选结构。出现的次数不确定的话&#…...
docker发布项目及使用外部文件的情况处理
适用docker环境已搭建好 首先项目打jar包:server-cdzh-2.1.0-SNAPSHOT.jar 创建Dockerfile FROM java:8 ADD server-cdzh-2.1.0-SNAPSHOT.jar cdzh.jar EXPOSE 60156 ENTRYPOINT ["java","-jar","/cdzh.jar"] 在linux服务器新建…...
CSS 中哪些属性可以继承
1. 字体属性: font、font-style、font-variant、font-weight、font-size、line-height等属性是字体样式的属性,都可以被子元素继承。 2. 文本属性: color、text-indent、text-align、text-decoration、text-transform、letter-spacing、wo…...
vue cli构建的项目出现 Uncaught runtime errors
使用 vue/cli 脚手架构建的项目,在 npm run dev 运行后,页面出现 Uncaught runtime errors 报错遮罩层,如下图所示。 报错原因 这种错误通常是运行时出的问题,可能是网络错误,可能是变量未定义等等。 这种错误默认在开…...
透过源码理解Flutter InheritedWidget
InheritedWidget的核心是保存值和保存使用这个值的widget,通过对比值的变化,来决定是否要通知那些使用了这个值的widget更新自身。 1 updateShouldNotify和notifyClients InheritedWidget通过updateShouldNotify函数控制依赖其的子组件是否在Inherited…...
天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。
今天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。 1.线程池核心的参数 1.线程核心数- 线程池中始终保持的活动线程数量。 2.最…...
使用finksql方式将mysql数据同步到kafka中,每次只能同步一张表
使用finksql方式将mysql数据同步到kafka中,每次只能同步一张表 package flink;import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.table.api.TableResult; import org.apache.flink.table.api.bridge.java.…...
ios开发 swift5 苹果系统自带的图标 SF Symbols
文章目录 1.官网app的下载和使用2.使用代码 1.官网app的下载和使用 苹果官网网址:SF Symbols 通过上面的网址可以下载dmg, 安装到自己的mac上 貌似下面这样不能展示出动画,还是要使用动画的代码 .bounce.up.byLayer2.使用代码 UIKit UIImage(system…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...

