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

【自动化测试】之PO模式介绍及案例

概念

PO(Page Object)设计模式是一种面向对象( 页面对象)的设计模式,将测试对象及单个的测试步骤封装在每个Page对象以page为单位进行管理。

优点

  1. 可以使代码复用
  2. 降低维护成本
  3. 提高程序可读性和编写效率。
  4. 可以将页面定位和业务操作分开,测试对象(元素对象)和测试脚本(用例脚本)
  5. 提高用例的可维护

 

非PO模式PO模式
面向过程的线性脚本POM把页面元素定位和业务操作流程分开,实现松耦合
复用性性差UI元素的改变不需要修改业务逻辑代码,只需要找到对应的PO页修改定位即可,数据代码分离
维护性差PO能使代码更具有可读性,高复用性、可维护性

PO三层模式:

主要分三层:
1.base层(对象库层):page页面一些公共的方法。如:初始化、元素定位、点击、输入、获取文本、截图等方法;
2.page层(操作层):封装对元素的操作。将每个涉及的元素操作单独封装一个操作方法,然后根据需求组装操作步骤,如登录方法=输入帐号+输入密码+点击登录三个操作进行组装;
3.scripts层(业务层):导包调用 page页面,使用单元测试框架对业务逻辑进行封装测试。如:实现登录,直接调用page组装的登陆方法即可。
三者的关系:page层继承base层,scripts层调用page层

 

案例:

项目结构介绍:

创建项目,如下图

1. 构建基础的 BasePage 对象层

创建driver,浏览器驱动封装

# encoding='UTF-8'
# 浏览器启动
from selenium import webdriver
def browser():driver=webdriver.Chrome()# driver.get("http://www.baidu.com")return driver

 

创建myuni.py文件,初始化封装,

定义一个继承自unittest.TestCase的测试用例类

定义setUp和tearDown,这两个方法与junit相同,即如果定义了则会在每个测试case执行前先执行setUp方法,执行完毕后执行tearDown方法。

# encoding='UTF-8'
import unittest
from driver import *
class StartEnd(unittest.TestCase):def setUp(self):self.driver=browser()self.driver.implicitly_wait(10)self.driver.maximize_window()def tearDown(self):self.driver.quit()

创建function.py文件,截图功能

# encoding='UTF-8'
import os
from selenium import webdriver# 截图
def insert_img(driver,filename):func_path=os.path.dirname(__file__)# print(func_path)base_dir=os.path.dirname(func_path)# print(base_dir)# 将路径转化为字符串base_dir=str(base_dir)# 对路径的字符串进行替换base_dir=base_dir.replace("\\","/")# print(base_dir)# 获取项目文件的要目录路径base=base_dir.split('/Website')[0]# print(base)# 指定截图存放路径(注意路径最后要加/)filepath=base+'/Website/test_report/screnshot/'+filenamedriver.get_screenshot_as_file(filepath)if __name__=='__main__':driver=webdriver.Chrome()driver.get("http://www.sogou.com")

2. 构建首页的 Page 层(操作层)

创建BasePage.py文件,判断打开的页面是否是预期的页面

# encoding='UTF-8'
from time import sleepclass Page():def __init__(self,driver):self.driver=driverself.base_url="http://localhost"self.timeout=10def _open(self,url):url_=self.base_url+url# print("这个页面url是:%s"%url_)self.driver.maximize_window()self.driver.get(url_)# sleep(2)assert self.driver.current_url==url_,'这不是我们想要的地址'def open(self):self._open(self.url)def find_element(self,*loc):return self.driver.find_element(*loc)

创建LoginPage.py文件,页面元素定位封装

# encoding='UTF-8'
from BasePage import *
from selenium.webdriver.common.by import Byclass LoginPage(Page):url='/news/'username_loc=(By.NAME,'username')password_loc=(By.NAME,'password')submit_loc=(By.NAME,'Submit')def type_username(self,username):self.find_element(*self.username_loc).send_keys(username)def type_password(self,password):self.find_element(*self.password_loc).send_keys(password)def type_submit(self):self.find_element(*self.submit_loc).click()def login_action(self,username,password):self.open()self.type_username(username)self.type_password(password)self.type_submit()loginPass_loc=(By.LINK_TEXT,'我的空间')loginErr_loc=(By.LINK_TEXT,'加入收藏')def type_loginPass_hint(self):return self.find_element(*self.loginPass_loc).textdef type_loginErr_hit(self):return self.find_element(*self.loginErr_loc).text

3.构建业务层

  • 创建test_login.py文件
  • 导包:function、myunit、LoginPage
  • 创建LoginTest类,继承myunit.StartEnd,初始化方法
  • 定义测试用例,名字以test开头,unittest会自动将test开头的方法放入测试用例集中
  • 实现登录,调用LoginPage组装的登陆方法,输入用户名、密码、点击登录、断言,截图

 

# encoding='UTF-8'
import unittest
from model import function,myunit
from page_object.LoginPage import *
from time import sleepclass LoginTest(myunit.StartEnd):def test_login1_normal(self):print("test_login1_normal测试开始")po=LoginPage(self.driver)po.login_action("yuruyi","12345678")sleep(5)self.assertEqual(po.type_loginPass_hint(),'我的空间')function.insert_img(self.driver,"login_normal.png")print("test_login1_normal执行结束")def test_login2_PasswdError(self):print("test_login2_PasswdError测试开始")po=LoginPage(self.driver)po.login_action("yuruyi","1234567")sleep(5)self.assertEqual(po.type_loginErr_hit(),'加入收藏')function.insert_img(self.driver,"login_Err.png")print("test_login2_PasswdError执行结束")def test_login3_empty(self):print("test_login3_empty测试开始")po = LoginPage(self.driver)po.login_action("", "")sleep(5)self.assertEqual(po.type_loginErr_hit(), '加入收藏')function.insert_img(self.driver, "login_empty.png")print("test_login3_empty执行结束")if __name__=='__main__':unittest.main()
常用断言方法:

4. 构建用例集,执行文件,输出自动化测试报告

在测试用例、测试文件比较多的时候,使用统一的主测试执行文件进行测试用例的执行非常方便,这就需要结合discover方法和TextTestRunner进行。

# encoding='UTF-8'
import unittest
# 测试报告模板
from HTMLTestRunnerCN import HTMLTestRunner
import timereport_dir='./test_report'
test_dir='./test_case'print("start run test case")
discover=unittest.defaultTestLoader.discover(test_dir,pattern="test_login.py")now=time.strftime("%Y-%m-%d %H_%M_%S")
report_name=report_dir+'/'+now+'result.html'print("start write report..")
#使用runner运行器运行测试集
with open(report_name,'wb')as f:runner=HTMLTestRunner(stream=f,title="Test Report",description="localhost login test")runner.run(discover)f.close()
print("Test end")

 

测试报告模板

感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

 

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取 

 

相关文章:

【自动化测试】之PO模式介绍及案例

概念 PO(Page Object)设计模式是一种面向对象( 页面对象)的设计模式,将测试对象及单个的测试步骤封装在每个Page对象以page为单位进行管理。 优点 可以使代码复用降低维护成本提高程序可读性和编写效率。可以将页面定位和业务操…...

3D-Genome | Hi-C互作矩阵归一化指南

Hi-C 是一种基于测序的方法,用于分析全基因组染色质互作。它已广泛应用于研究各种生物学问题,如基因调控、染色质结构、基因组组装等。Hi-C 实验涉及一系列生物化学反应,可能会在输出中引入噪声。随后的数据分析也会产生影响最终输出噪声&…...

【设计者模式】单例模式

文章目录 1、模式定义2、代码实现(1)双重判空加锁方式两次判空的作用?volatile 关键字的作用?构造函数私有? (2)静态内部类【推荐】(3)Kotlin中的单例模式lateinit 和 by…...

Windows7缺失api-ms-win-crt-runtime-l1-1-0.dll的解决方法

api-ms-win-crt-runtime-l1-1-0.dll是一个在Windows操作系统环境下至关重要的动态链接库文件(DLL),它是Microsoft Visual C Redistributable的一部分,负责实现C运行时库的相关功能。这个特定的DLL文件提供了大量的底层运行支持&am…...

coqui-ai/TTS 安装使用

Coqui AI的TTS是一款开源深度学习文本转语音工具,以高质量、多语言合成著称。它提供超过1100种语言的预训练模型库,能够轻松集成到各种应用中,并允许用户通过简单API进行个性化声音训练与微调。其技术亮点包括但不限于低资源适应性&#xff0…...

Spring AOP相关注解及执行顺序

Aspect(切面):用于标识一个类是切面的注解。通常与其他通知注解一起使用,定义切面类。 Pointcut(切点): 注解来定义切点,它用于描述哪些连接点将会被通知所通知。 连接点&#xff…...

C++从零开始的打怪升级之路(day44)

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料 那么开启正题 今天分享的是关于二叉搜索树的知识点 1.二叉搜索树概念 二叉搜…...

[C++核心编程](七):类和对象——运算符重载*

目录 四则运算符重载 左移运算符重载 递增运算符重载 赋值运算符重载 关系运算符重载 函数调用运算符重载 对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型 四则运算符重载 对自定义数据类型实现四则运算(加减乘除&…...

什么是MVC和MVVM

**MVC和MVVM是两种流行的软件架构模式,它们在前端开发中被广泛采用来组织代码和管理应用程序的复杂性**。具体如下: MVC(Model-View-Controller): 1. 模型(Model):负责管理数据和业…...

物体检测-系列教程23:YOLOV5 源码解析13 (SPP层、Flatten模块、Concat模块、Classify模块)

😎😎😎物体检测-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 点我下载源码 17、SPP模块 17.1 SPP类 SPP是一种特殊的池化策略,最初在YOLOv3-SPP中被使用…...

2024.3.6每日一题

LeetCode 找出数组中的 K -or 值 题目链接:2917. 找出数组中的 K-or 值 - 力扣(LeetCode) 题目描述 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 nums 中的 K-or 是一个满足以下条件的非负整数: 只有在 nums 中&…...

YOLOSHOW - YOLOv5 / YOLOv7 / YOLOv8 / YOLOv9 基于 Pyside6 的图形化界面

YOLOSHOW 是一个基于 PySide6(Qt for Python)开发的图形化界面应用程序,主要用于集成和可视化YOLO系列(包括但不限于YOLOv5、YOLOv7、YOLOv8、YOLOv9)的目标检测模型。YOLOSHOW 提供了一个用户友好的交互界面&#xff…...

sql高级

sql高级 SQL SELECT TOP 子句 SELECT TOP 子句用于规定要返回的记录的数目。 SELECT TOP 子句对于拥有数千条记录的大型表来说,是非常有用的。 **注意:**并非所有的数据库系统都支持 SELECT TOP 语句。 MySQL 支持 LIMIT 语句来选取指定的条数数据, O…...

更快更强,Claude 3全面超越GPT4,能归纳15万单词

ChatGPT4和Gemini Ultra被Claude 3 AI模型超越了? 3月4日周一,人工智能公司Anthropic推出了Claude 3系列AI模型和新型聊天机器人,其中包括Opus、Sonnet和Haiku三种模型,该公司声称,这是迄今为止它们开发的最快速、最强…...

devc++小游戏3.8.5

导航: Dev-c跑酷小游戏 1.0.0 devc跑酷小游戏1.2.5 devc跑酷游戏1.2.6 devc跑酷游戏2.0.0 devc跑酷游戏2.0.1 devc跑酷游戏2.4.0 devc跑酷小游戏3.5.0 更新内容 重磅回归,存档搞定!!! 每一关需要前一关已…...

Java网络通信TCP

目录 TCP两个核心类 服务端 1.用ServerSocker类创建对象并且手动指定端口号 2.accept阻塞连接服务端与客户端 3.给客户端提供处理业务方法 4.处理业务 整体代码 客户端 1.创建Socket对象,并连接服务端的ip与端口号 2.获取Socket流对象,写入数据…...

层级锁笔记

注意看test_hierarchy_lock函数&#xff1a;如果thread t2的不注释&#xff0c;就会报错。 这是因为层级锁 更强调单个线程内上锁的顺序。 线程t2已经获取了hmtx2&#xff0c;再试图获取hmtx1就会因为违反层级顺序而抛出异常。 #include <mutex> #include <thread&g…...

基于SpringBoot+Vue 的专家医院预约挂号系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

计算机基础专升本笔记十二-Excel常用快捷键大全

计算机基础专升本笔记十二-Excel常用快捷键大全 Excel常用快捷键 按键作用Ctrl 0隐藏列Ctrl 1设置单元格格式Ctrl 2添加或取消字体加粗Ctrl 3添加或取消字体倾斜Ctrl 4添加或取消下划线Ctrl 5添加或取消删除线Ctrl 6隐藏或显示图形Ctrl 7隐藏工具栏Ctrl 8隐藏或显示…...

制作耳机壳的UV树脂和塑料材质相比优势有哪些?

制作耳机壳的UV树脂相比塑料材质有以下优势&#xff1a; 高强度与耐磨性&#xff1a;UV树脂具有高强度和耐磨性&#xff0c;能够更好地保护耳机内部零件&#xff0c;延长耳机使用寿命。相比之下&#xff0c;塑料材质可能较易磨损或刮伤。耐高温&#xff1a;UV树脂具有较好的耐…...

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

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

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...