当前位置: 首页 > news >正文

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了传统的设计中,在新增测试用例之后,代码会有以下几个问题&#xff1a…...

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…...

可拖动表格

支持行拖动&#xff0c;列拖动 插件&#xff1a;sortablejs UI: elementUI <template><div><hr style"margin: 30px 0;"><div><!-- 数据里面要有主键id&#xff0c; 否则拖拽异常 --><h2 style"margin-bottom: 30px&qu…...

C++语法基础

这里写目录标题 基础语法第一个程序变量常量的定义关键字标识符命名 &#xff08;变量命名&#xff09;sizeof的使用实型&#xff08;浮点型&#xff09;字符型转义字符字符串的定义 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 基础语法 第一个程序 …...

Windi CSS和Tailwind CSS以及UnoCSS

最近合作在写一个vue3ts的项目&#xff0c;看到其他人用了一种写法&#xff0c;我觉得很奇怪&#xff0c;之前没见过&#xff0c;他是这样写的 <div class"news flex-1 h-40px flex"></div>我不理解的是为什么这样写就会让这个div的高度就是40px,好多代码…...

c++ opencv将彩色图像按连通域区分

要将彩色图像按连通域区分&#xff0c;您可以使用 OpenCV 中的 cv::connectedComponents 函数。 下面是一个简单的示例代码&#xff0c;说明如何使用 cv::connectedComponents 函数来检测并标记图像中的连通域&#xff1a; #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 布局标签 一、基本了解 网页组成&#xff08;index.html页面&#xff09;&#xff1a; HTML标记语言…...

2.1: Dubbo的基本应用-负载均衡,集群容错,服务降级

负载均衡 官网地址&#xff1a; http://dubbo.apache.org/zh/docs/v2.7/user/examples/loadbalance/ 如果在消费端和服务端都配置了负载均衡策略&#xff0c; 以消费端为准。 这其中比较难理解的就是最少活跃调用数是如何进行统计的&#xff1f; 讲道理&#xff0c; 最少活跃数…...

正则常见问题及解决方案

使用正则处理问题的基本思路。有一些方法比较固定&#xff0c;比如将问题分解成多个小问题&#xff0c;每个小问题见招拆招&#xff1a;某个位置上可能有多个字符的话&#xff0c;就⽤字符组。某个位置上有多个字符串的话&#xff0c;就⽤多选结构。出现的次数不确定的话&#…...

docker发布项目及使用外部文件的情况处理

适用docker环境已搭建好 首先项目打jar包&#xff1a;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. 字体属性&#xff1a; font、font-style、font-variant、font-weight、font-size、line-height等属性是字体样式的属性&#xff0c;都可以被子元素继承。 2. 文本属性&#xff1a; color、text-indent、text-align、text-decoration、text-transform、letter-spacing、wo…...

vue cli构建的项目出现 Uncaught runtime errors

使用 vue/cli 脚手架构建的项目&#xff0c;在 npm run dev 运行后&#xff0c;页面出现 Uncaught runtime errors 报错遮罩层&#xff0c;如下图所示。 报错原因 这种错误通常是运行时出的问题&#xff0c;可能是网络错误&#xff0c;可能是变量未定义等等。 这种错误默认在开…...

透过源码理解Flutter InheritedWidget

InheritedWidget的核心是保存值和保存使用这个值的widget&#xff0c;通过对比值的变化&#xff0c;来决定是否要通知那些使用了这个值的widget更新自身。 1 updateShouldNotify和notifyClients InheritedWidget通过updateShouldNotify函数控制依赖其的子组件是否在Inherited…...

天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。

今天去面试的时候&#xff0c;遇到一个问题。我三个任务&#xff0c;ABC&#xff0c;我怎么让A执行完执行B&#xff0c;B执行完执行C 3个并行线程&#xff0c;如何解决。程池的核心运行原理和参数。 1.线程池核心的参数 1.线程核心数- 线程池中始终保持的活动线程数量。 2.最…...

使用finksql方式将mysql数据同步到kafka中,每次只能同步一张表

使用finksql方式将mysql数据同步到kafka中&#xff0c;每次只能同步一张表 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的下载和使用 苹果官网网址&#xff1a;SF Symbols 通过上面的网址可以下载dmg, 安装到自己的mac上 貌似下面这样不能展示出动画&#xff0c;还是要使用动画的代码 .bounce.up.byLayer2.使用代码 UIKit UIImage(system…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...