基于Python+Selenium+Unittest+PO设计模式

news2024/11/19 6:37:52

一、什么是PO设计模式(Page Object Model)
1、Page Object是一种设计模式,它主要体现在对界面交互细节的封装上,使测试用例更专注于业务的操作,从而提高测试用例的可维护性。

2、一般PO设计模式有三层

第一层:

对Selenium 进行二次封装,定义一个所有页面都继承的 BasePage ,
封装 Selenium 基本方法 例如:元素定位,元素等待,导航页面 ,
不需要全部封装,用到多少方法就封装多少方法。
第二层:

页面元素进行分离,每个元素只定位一次,隔离定位,如果页面改变,只需要改变相应的元素定位;
业务逻辑分离 或 操作元素动作分离
第三层:

使用单元测试框架对业务逻辑进行测试

二、为什么要使用PO设计模式
页面频繁变化,(页面html结构等变化)导致页面UI元素频繁变动,元素定位改变
传统线性自动化(面向过程开发),用例中需要反复的定位同一个元素
每当页面发生变化的时候,需要在用例中寻找变动的部分,工作量大,容易产生遗漏,不容易维护
三、PO设计模式的六大原则
公共方法代表页面提供的服务
不要暴露细节
不要在封装的框架中做断言
方法可以return到新打开的页面
不要对所有元素建模,仅对自己关注的元素建模
相同的行为会产生不同的结果,可以封装不同的结果
四、PO设计模式实例
以公司的统一登录作为项目例子,用PO设计模式实现登陆:

1、手工用例:

2、用PO模式实现自动化用例

项目目录

Base.py
login_page.py
from Page import Base
 
# 创建LoginPage类继续BasePage类
class LoginPage(Base.BasePage):
    '''统一平台登录Page层,登录页面封装操作到的元素'''
    '''第二层:页面元素进行分离,每个元素只定位一次,操作元素动作分离'''
    # 定义url变量,供父类中的open()方法使用
    url ="https://test01....cn/#/login"
    # 用户名输入框定位
    def form_username(self,user_name):
        return self.by_id("name").send_keys(user_name) # 使用了父类的self.by_id()方法定位元素,简洁了不少
    # 密码输入框定位
    def form_password(self,pass_word):
        return self.by_id("password").send_keys(pass_word)
    # 登录按钮定位
    def button_login(self):
        return self.by_xpath("//*[text()='登录']").click()

 test_login.py

from Page import login_page
import unittest
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.keys import Keys
from CommonMethod import LogUtil
 
logger = LogUtil.logs() # 调用封装的日志方法,将日志输出到控制台以及写入文件
 
class LoginCase(unittest.TestCase):
    '''第三层:用单元测试框架对业务逻辑进行测试'''
    '''使用LoginPage类及它所继承的父类中的方法'''
    @classmethod
    def setUpClass(cls):
        # 实例化webdriver,俗称:打开浏览器
        cls.driver = webdriver.Firefox(executable_path='E:\\UI test\\UnittestProject\\Driver\\geckodriver.exe')
        cls.driver.implicitly_wait(10)
    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()
    def test_login_success(self):
        page = login_page.LoginPage(self.driver) # 需要用到哪个Page类时,只需要将它传入浏览器驱动,就可以使用该类中提供的方法了
        page.open()
        page.form_username("XXX")
        page.form_password("123456")
        page.button_login()
        sleep(2)
        self.assertEqual(page.get_current_url(), "https://test01....cn/#/home")
        print("登录成功,用例执行结果通过,当前的url为"+ page.get_current_url())
        sleep(1)
    def test_login_fail(self):
        page = login_page.LoginPage(self.driver)
        page.open()
        page.form_username("XXX11")
        page.form_password("123456")
        page.button_login()
        self.assertNotEqual(page.get_current_url(), "https://test01....cn/#/home")
        print("登录失败,用例执行结果通过,当前的url为"+ page.get_current_url())
        page.form_username(Keys.CONTROL+'a') # 输入组合键Ctrl+a,全选输入框内容
        page.form_username(Keys.BACK_SPACE) # 删除键,删除选中的内容
        page.form_password(Keys.CONTROL + 'a')
        page.form_password(Keys.BACK_SPACE)
        sleep(1)
if __name__ == '__main__':
    unittest.main(verbosity=2)
执行结果

在test_login.py中有调用封装的日志方法,这里把封装的日志附上,在CommonMethod目录下的LogUtil.py

 LogUtil

 五、其他补充
1、相同的行为会产生不同的结果,可以封装不同的结果:在login_page针对【登录】按钮封装了2个方法

2、方法可以return到新打开的页面:在login_page针对【登录】按钮封装,封装了之后要return新页面或其他信息。test_login调用时命名变量来接收这个函数就行了,比如indexurl = page.button_login_success(),在后面断言可以用indexurl变量来跟预期的url断言

 # 登录失败封装
    def button_login_fail(self):
        self.by_xpath("//span[text()='登录']").click()
        toast = self.by_xpath("//p[text()='账号或密码错误!']").text
        return toast
 
    # 登录成功封装
    def button_login_success(self):
        self.by_xpath("//span[text()='登录']").click()
        sleep(2)
        windows = self.driver.window_handles# 获取打开的多个窗口句柄
        self.driver.switch_to.window(windows[-1])# 切换到当前最新打开的窗口
        indexurl = self.get_current_url()
        return indexurl

3、断言:可以通过url、页面标题、text来断言

'''断言跳转的地址,通过try except语句块来进行测试断言,在实际自动化测试脚本开发中,经常要用到处理异常'''
        try:
            self.assertEqual(indexurl,"https://qa-xxxt/add")
            print("点击创建,正确跳转到新页面" + indexurl)
        except AssertionError as msg:
            print("没有跳转到正确页面,当前跳转的地址为"+addurl+"\n报错信息如下"+format(msg))
            '''当断言失败时会抛出异常测试用例执行失败,输出提示信息后重新将异常抛出,即raise,
            若不重新抛出,用例则永远是显示执行成功的,因为它把异常处理掉了'''
            raise msg
  try:
            self.assertEqual(toast, "账号或密码错误!")
            print("登录失败用例场景执行通过,正确弹出提示信息为:" + toast)
        except AssertionError as msg:
            print("错误提示语与预期结果不一致,请检查"+ format(msg))
            raise msg
  try:
            self.assertEqual(toast, "账号或密码错误!")
            print("登录失败用例场景执行通过,正确弹出提示信息为:" + toast)
        except AssertionError as msg:
            print("错误提示语与预期结果不一致,请检查"+ format(msg))
            raise msg
总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

 

 

                                                          全套资料获取方式:点击下方小卡片自行领取即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1124646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【鸿蒙软件开发】文本显示(Text/Span)

文章目录 前言一、Text控件1.1 创建文本string字符串引用Resource资源 1.2 添加子组件创建Span文本装饰线和样式文本装饰线设置文字一直保持大写/小写添加事件。 1.3 自定义文本样式文本对齐长文本处理设置行高通过decoration属性设置文本装饰线样式及其颜色。通过baselineOffs…

功率放大器在PZT陶瓷薄膜压电传感器研究中的应用

随着科技的进步和工业发展的需求,对于压力测量和控制的需求日益增加。压力传感器作为一种关键的传感器器件,在机械、自动化、医疗、航空等多个领域都有广泛应用。PZT陶瓷薄膜压电传感器由于其响应速度快、精度高、稳定性好等优点,成为了许多应…

OTA: Optimal Transport Assignment for Object Detection 论文和代码学习

OTA 原因步骤什么是最优传输策略标签分配的OT正标签分配负标签分配损失计算中心点距离保持稳定动态k的选取 整体流程代码使用 论文连接: 原因 1、全部按照一个策略如IOU来分配GT和Anchors不能得到全局最优,可能只能得到局部最优。 2、目前提出的ATSS和P…

做数据可视化,谨记三大要点

数据可视化报表就是“一图胜千言”的最佳例子。数据可视化,也就是将数据图形化、图表化,以良好的视觉效果呈现数据,达到发现、分析、预测、监控、决策等目的。要想做出一份优秀的数据可视化报表,那就要在做报表时谨记三大要点&…

3D模型在线格式转换工具

单模型上传格式 支持格式说明 支持RAR和ZIP压缩包上传,压缩包大小按原始文件大小计算,压缩包内只能包含一个模型文件 超过500MB的模型请联系客服 您也可以下载老子云客户端进行批量上传 不同会员级别的模型上传大小有不同的限制,详情请查询…

越来越好用的Edge浏览器,盘点Edge浏览器功能丨插件

前些年, Edge 浏览器也宣布加入 Chromium 内核;它的前身是IE浏览器, Edge之所以越来越多人用的一个原因是因为它的内核是Google Chrome的Chromium,而且不需要膜法就可以使用,这一点Chrome浏览器还不行,访问…

分拣设备运动仿真

这一次我们来分享一下如何在Solidworks 中做出传送台的分拣动作并通过分拣动作生成过程动画,以便于我们可以用于产品展示又或者验证运行程序无误的情况下结构是否会影响输送效率。 首先创建一个新的运动算例 将窗口切换至Motion分析 在设置之前我们先理清设置传送带…

税务某局 webpack 登录接口逆向分析

持续创作文章,只是为了更好的思考 这里不多介绍了,我放一张图大家就明白是什么接口了。这里只介绍整体加密逻辑,有些细的地方大家自行调整。 本次逆向的网址是 aHR0cHM6Ly90cGFzcy5qaWxpbi5jaGluYXRheC5nb3YuY246ODQ0My8jL2xvZ2luP3JlZGly…

vue3实现详情页返回列表页,返回原来列表页滚动条所在的位置

keepAlive缓存页面 组合式API 第一步第二步第三步第四步 第一步 首先在路由文件的meta里面定义 meta: {keepAlive: false, },第二步 在app.vue 根文件下定义代码 <template><keep-alive><router-view v-if"route.meta.keepAlive" /></keep-…

基于springboot实现广场舞团平台系统项目【项目源码+论文说明】

基于springboot实现广场舞团管理平台系统 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&am…

软设上午题错题知识点8

软设上午题错题知识点8 1、IPv4用32位二进制表示&#xff0c;能够表示的地址空间是232&#xff0c;IPv6用128位二进制表示&#xff0c;能够表示的地址空间是2128&#xff0c;本题选择2128 /232296 。 2、在应用散列函数构造哈希表&#xff08;或散列表&#xff09;时&#xf…

使用docker部署flask接口服务 一

文章目录 一&#xff1a;说明二&#xff1a;dockerfile 参数说明1. 一般常用的 参数&#xff0c;以及它的含义2. 我自己的 dockerfile 三&#xff1a;示例操作1. Gunicorn Gevent启动服务的好处2. 用Gunicorn Gevent的好处&#xff1a;3. Gunicorn Gevent的 使用示例4. 创建…

“数字赋能、智创未来”第三届中国(宁波)软件峰会暨程序员节即将开启

在“八八战略”的指引下,我们深入实施数字经济创新提质“一号发展工程”,以打造“全球智造创新之都”为目标,强化数字赋能、绿色赋能、低碳赋能、融合赋能,全速推动数字经济和实体经济深度融合。第三届(宁波)软件峰会暨程序员节将于10月24日下午在宁波泛太平洋大酒店三楼大宴会…

优优嗨聚集团:旅游经济繁荣,助力当地外卖市场崛起

随着全球旅游经济的飞速发展&#xff0c;越来越多的人选择在假期或周末出游。而在旅游过程中&#xff0c;餐饮是一个不可或缺的环节。近年来&#xff0c;随着移动支付和互联网技术的普及&#xff0c;外卖行业逐渐崛起&#xff0c;为旅游经济注入了新的活力。 一、旅游经济带动外…

口袋参谋:如何一键获取竞品数据?这招实用!

​在淘宝天猫上开店&#xff0c;市场竞争日益激烈&#xff0c;想要做好店铺&#xff0c;我们就不得不去分析竞品的数据了。 很多卖家开店后&#xff0c;一上来就直接卡在类目前10&#xff0c;折腾了一两个月才发现自己对标错了对象&#xff0c;最终竹篮打水一场空。 所以&…

Linux下 /etc/shadow内容详解

/etc/shadow 文件&#xff0c;用于存储 Linux 系统中用户的密码信息&#xff0c;又称为“影子文件”。 前面介绍了 /etc/passwd 文件&#xff0c;由于该文件允许所有用户读取&#xff0c;易导致用户密码泄露&#xff0c;因此 Linux 系统将用户的密码信息从 /etc/passwd 文件中…

以赛促教,以赛促研 ——计算机科学系举办“火焰杯”软件测试开发选拔赛颁奖仪式

颁奖仪式 2023年3月9日&#xff0c;第三届“火焰杯”软件测试开发选拔赛颁奖仪式在南海楼124会议室举行&#xff0c;计算机科学系系主任龙锦益教授、指导老师孙玉霞副教授、测吧科技有限公司王雪冬总监及获奖同学参加了颁奖仪式。 会议伊始&#xff0c;龙锦益教授对王雪冬总监…

安防视频监控平台EasyCVR查询告警后,无法自动清除记录该如何优化?

视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#xff0c;也能支…

中国芯片制造厂商无惧封禁,订单一路飙升 | 百能云芯

随着美国对中国半导体行业实施更严格的限制措施&#xff0c;中国的芯片制造厂商成为了不可忽视的受益者。根据外媒报道&#xff0c;中国顶尖的芯片代工厂为了加速自主科技发展&#xff0c;已经开始更多地依赖国内制造的设备&#xff0c;这导致了中国芯片制造厂商近几个月来接到…

前端KOA搭建服务器——part1

目录 koa简介前端项目搭建koa环境第一步&#xff1a;新建项目第二步&#xff1a;环境初始化&#xff0c;安装依赖初始化项目&#xff0c;生成package.json文件安装koa依赖安装koa-router 路由管理依赖安装dotenv 环境变量依赖安装nodemon 热启动依赖 第三步&#xff1a;代码调用…