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…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

