web自动化之PO模式

PO模式

1、为什么需要PO思想?

首先我们观察和思考一下,目前我们写的作业脚本的问题: 元素定位和操作动 作写到一起了,这就就会用导致一个问题:

  • UI的页面元素比较容易变化的,所以元素定位和脚本操作写到一起,一旦 元素发生了变化,这些脚本都需要修改
  • 特别是登录页面在很多个页面都会涉及到 被引用,那么就会导致: 维护成 本比较大。 所以,我们通过PO模式来解决这个问题。

2、什么是PO模式

Page Object Model(页面对象模型), 或者也可称之为POM。在UI自动化测试 广泛使用的一种分层设计模式。

page就是网页的页面层,object就是封装的LoginPage 类:每一个页面一个 类,包含业务逻辑和测试对象

  • 页面元素元素定位: 定义为类的属性
  • 页面的操作行为 : 定义为类的方法
  • 业务逻辑: 对页面的操作 为了得到实际结果的过程 和步骤 ,这是测试 对象

测试用例+ 测试数据层: 单独维护。 包含测试逻辑步骤和测试用例

  • 测试逻辑: 测试部分 ,预期结果和实际结果的对比 ,这是测试用例

PO核心是通过页面层封装所有的页面元素及操作,测试用例层通过调用页面层 操作组装业务逻辑。

PO模式的核心思想:体现了业务逻辑和测试逻辑 的分离,测试用例和测试对象分离

以登录操作为例:

  • 获取页面登录错误信息 登出 等操作都是业务逻辑,单独进行PageObject 的封装。
  • 用例里只传用例数据,不会出现元素定位的代码。包括断言里也不要出现 元素定位。

PO模式最终的实现效果:

页面层:

  • 页面类A(A1 A2 A3)
  • 页面类B(B1 B2 B3) 页面类C(C1 C2 C3)

用例层:

  • 用例1 = A1 + B2 + C3
  • 用例2 = A1 + B2 + C1

PO模式优点:

  • 提高测试用例的可读性
  • 提高测试用例可维护性
  • 减少代码重复

我们现在以登录页面为例:登录页面类

因为这个页面里有元素定位 + 元素操作: 把这些东西最好是封装在一起,方便 被用例层调用。

  • 页面里的元素: 写成类的属性
    • 用元组形式表示;因为后面显示等待都是用元组调用的;调用用self调 用 ;
    • 并不需要一次性把所有元素都写出来,可以后续扩展
  • 页面的操作: 封装成实例方法
    • driver先没有,
    • 可以作为参数 一些变化的数据也参数化

三层PO思想【BasePage封装思想】

但是这样写还有个问题:既然每个元素都用显示等待操作,每个页面都写一 遍太麻烦,冗余度太高了;而且每个页面都有一些其他的共同的操作,比如点 击,输入文本等;那么每个页面都重复写,是不是可以进一步优化呢?

  • 这些每个页面都会调用的方法【等待,点击,输入文本等】,就属于公共 方法; BasePage 封装思想
  • 用三层PO模式: 公共页面的内容单独提取出来封装:这也叫做 。封装成为一个BasePage类。
  • 其他页面自己独有的元素和方法依然放在单独页面类里封装;需要用到 basepage类的内容的时候,如何实现?--- 类的继承实现

所以新建一个common的目录,建一个base_page的py文件,方所有的功能 方法。

  • BasePage 用来存放所有页面类的公共部分,一些公共的操作(显式封装)
  • 封装一个BasePage的类,里面的方法都是每个页面都要用的公共的方法。

base_page.py
from time import sleepimport pyautogui
import pyperclip
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChainsclass BasePage:# driver每个方法都用,如果直接定位参数,没有办法实现实例方法共享,所以可以定义为实例属性 实现共享def __init__(self,driver): # 初始化方法里定义了以参数  到时候实例化对象传参"""初始化函数 定义driver作为实例属性 实例实例方法共享这个实例属性"""self.driver = driver# 操作和行为 行为为实例方法def wait_element_clickable(self, locator):web_element = WebDriverWait(self.driver, 8, 0.5).until(EC.element_to_be_clickable(locator))return web_elementdef wait_element_visible(self, locator):web_element = WebDriverWait(self.driver, 8, 0.5).until(EC.visibility_of_element_located(locator))return web_elementdef wait_element_presence(self, locator):web_element = WebDriverWait(self.driver, 8, 0.5).until(EC.presence_of_element_located(locator))return web_element# 1、普通点击操作 --关键字def click_element(self,locator):self.wait_element_clickable(locator).click()# 2、鼠标点击操作def mouse_click(self,locator):# 先找到元素element = self.wait_element_visible(locator)# 用鼠标点击ActionChains(self.driver).click(element).perform()# 3、js点击操作def js_click(self,locator):# 先找到元素element = self.wait_element_visible(locator)# 用js传参点击self.driver.execute_script("arguments[0].click()",element)# 4、输入数据文本def input_text(self,locator,text):self.wait_element_visible(locator).send_keys(text)# 5、获取元素的文本 : 拿到这个文本 返回这个文本def get_text(self,locator):return self.wait_element_visible(locator).text# 6、获取元素的属性:拿到这个属性的值 设置为返回值def get_attribute(self,locator,attr_name):return self.wait_element_visible(locator).get_attribute(attr_name)# 7、窗口切换def switch_window(self,url):# 先拿到所有的窗口句柄handles = self.driver.window_handlesfor win in handles:if self.driver.current_url == url:  # 判断当前的页面是否为想要的url地址breakelse:self.driver.switch_to.window(win)  # 如果不是 继续切换# 8、移动鼠标def move_mouse(self,locator):element = self.wait_element_presence(locator)ActionChains(self.driver).move_to_element(element).perform()# 9、文件上传def file_upload(self,file_path):# 1、先复制路径pyperclip.copy(file_path)# 2、粘贴 -- hotkey 通过热键粘贴pyautogui.hotkey("ctrl", "v")pyautogui.press("enter", presses=2)
home_page_v1.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWaitclass HomePage:# 页面元素元素定位: 定义为类的属性 --元组loc_login = (By.XPATH, '//a[text()="登录"]')# 操作和行为 行为为实例方法def wait_element_clickable(self,driver,locator):web_element = WebDriverWait(driver, 8, 0.5).until(EC.element_to_be_clickable(locator))return web_elementdef wait_element_visible(self,driver,locator):web_element = WebDriverWait(driver, 8, 0.5).until(EC.visibility_of_element_located(locator))return web_elementdef wait_element_presence(self,driver,locator):web_element = WebDriverWait(driver, 8, 0.5).until(EC.presence_of_element_located(locator))return web_element# 点击首页里的登录链接按钮 打开登录页面 操作-- 定义为实例方法def click_login_link(self,driver):self.wait_element_visible(driver,self.loc_login).click()
test_login.py
"""
编写测试用例 执行测试用例 断言 的框架 - pytest框架
"""
from page_object.login_page_v1 import LoginPage
from page_object.home_page_v1 import HomePage
from selenium import webdriver# pytest框架编写测试用例
def test_login():driver = webdriver.Chrome()driver.maximize_window()driver.get("http://mall.lemonban.com:3344/")# 1、点击homepage 登录的链接 == 先实例化对象,再调用实例方法,实例方法要传参driverHomePage().click_login_link(driver)# 2、调用LoginPage里的login实例方法  执行登录操作== 先实例化对象,再调用实例方法,实例方法要传参LoginPage().login(driver,"lemon_py","12345678")

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

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

相关文章

如何将照片从 iPhone 传输到闪存驱动器【无质量损坏】

概括 人们喜欢用 iPhone 拍照,因为照片通常都很漂亮,这都要归功于 iPhone 令人惊叹的技术。但照片更新后会占用更多空间,并且您可能会开始收到没有存储空间的通知。因此,您可以将照片传输到 USB 驱动器,然后从 iPhone…

springboot-阿里羚羊 服务端埋点

官方文档 集成Java SDK 手动引入jar包「quickaplus-log-collector-java-sdk-1.0.1-SNAPSHOT.jar」 <dependency><groupId>com.alibaba.lingyang</groupId><artifactId>quickaplus-log-collector-java-sdk</artifactId><version>1.0.1&l…

应用案例 | 如何实时监测和管理冷链仓库温湿度?

一、项目背景 冷链仓库温湿度管理的重要性在于确保仓库内产品的质量和安全。通过遵循相关法规和标准&#xff0c;满足客户对产品质量的需求&#xff0c;同时实施有效的温湿度管理措施&#xff0c;可以降低成本并提高仓库作业效率。该项目的实施旨在帮助客户保证产品的新鲜度&a…

Java - AbstractQueuedSynchronizer

AQS简介 AQS全称AbstractQueuedSynchronizer&#xff0c;抽象队列同步器&#xff0c;是一个实现同步组件的基础框架。AQS使用一个int类型的成员变量state维护同步状态&#xff0c;通过内置的同步队列&#xff08;CLH锁、FIFO&#xff09;完成线程的排队工作&#xff0c;底层主…

echarts 散点图修改散点图中图形形状颜色大小

话不多说&#xff0c;直接上代码 let option {color:[xxx, xxx, xxx, xxx], //直接设置color可修改图形颜色title: {text: 散点图图形,},tooltip: {trigger: axis,axisPointer: {type: cross}},legend: {top: 2,right:2,itemWidth: 10,itemHeight: 10,textStyle:{fontSize:14}…

shell脚本条件语句和循环语句

文章目录 一、条件语句测试比较整数数值字符串比较逻辑运算双中括号&#xff08; &#xff09;{ }if语句结构case语句 二、循环语句基础知识for循环whileuntil双重循环及跳出循环 一、条件语句 测试 条件测试&#xff1a;判断某需求是否满足&#xff0c;需要由测试机制来实现…

视频分类——C3D使用

整体比较分散&#xff0c;可能很多源码都需要修改&#xff0c;需要有耐心。 一、数据准备 PS 调研后&#xff0c;上手容易代码比较简洁的是&#xff1a;https://github.com/Niki173/C3D/tree/main 因为源码很多参数都写死到了源码中&#xff0c;没有解耦&#xff0c;并且默…

5.20Git

版本控制工具Git&#xff0c;其他的工具还有SVN 共享代码&#xff0c;追溯记录&#xff0c;存储.c文件 Git实现的功能&#xff1a;回溯&#xff08;以前某个时间节点的数据情况&#xff09;共享&#xff08;大家共享修改&#xff09; Git&#xff1a;80% SVN&#xff…

The Missing Semester of Your CS Education(计算机教育中缺失的一课)

Shell 工具和脚本(Shell Tools and Scripting) 一、shell脚本 1.1、变量赋值 在bash中为变量赋值的语法是foobar&#xff0c;访问变量中存储的数值&#xff0c;其语法为 $foo。 需要注意的是&#xff0c;foo bar &#xff08;使用空格隔开&#xff09;是不能正确工作的&…

基于灰狼优化算法优化RBF(GWO-RBF)的数据回归预测(多输入多输出)

代码原理及流程 基于灰狼优化算法优化多输入多输出&#xff08;MIMO&#xff09;的RBF神经网络的数据回归预测&#xff0c;可以采取以下步骤&#xff1a; 1. 数据准备&#xff1a;准备包含多个输入特征和多个输出目标的数据集&#xff0c;确保数据已经经过预处理和归一化。 …

CSS基础(第二天)

Emmet语法 快速生成HTML结构语法 1. 生成标签 直接输入标签名 按tab键即可 比如 div 然后tab 键&#xff0c; 就可以生成 <div></div> 2. 如果想要生成多个相同标签 加上 * 就可以了 比如 div*3 就可以快速生成3个div 3. 如果有父子级关系的标签&#xff0c;可以…

算法刷题笔记 数的范围(C++实现)(二分法重要例题)

文章目录 题目描述题目思路题目代码&#xff08;C&#xff09;题目感想 题目描述 给定一个按照升序排列的长度为n的整数数组&#xff0c;以及q个查询。对于每个查询&#xff0c;返回一个元素k的起始位置和终止位置&#xff08;位置从0开始计数&#xff09;。如果数组中不存在该…

自动化测试--利用pytest实现整条业务链路测试

​ 概述 前面一章讲解了单个接口的测试&#xff0c;但是实际项目中&#xff0c;因为权限和登录状态的限制&#xff0c;大部分接口没办法直接访问到&#xff0c;这时候我们想访问到一个系统的接口&#xff0c;就需要模拟用户登录拿到用户的token和所拥有的权限之后再将这些信息…

vivado2020.2创建hls仿真工程实现led闪烁

下载vivado2020.2后会有这个出现在桌面 点击进入创建工程&#xff0c;这里注意不要有前面的\我再复制的时候复制错了导致创建失败 按f光标就会跳转到下一个f开头的函数处&#xff0c;要查找其他函数也同理 生成了一个synthesis summary文件 找到目录下生成的.v文件 an 点…

Pod进阶——资源限制以及探针检查

目录 一、资源限制 1、资源限制定义&#xff1a; 2、资源限制request和limit资源约束 3、Pod和容器的资源请求和限制 4、官方文档示例 5、CPU资源单位 6、内存资源单位 7、资源限制实例 ①编写yaml资源配置清单 ②释放内存&#xff08;node节点&#xff0c;以node01为…

有些错误,常犯常新、常新常犯:记录一个使用element-plus的tooltip组件的错误

使用element-plus的tooltip组件&#xff0c;最开始的写法是这样的&#xff1a; <el-tooltipclass"box-item"effect"dark"content"tooltip content" ><el-button v-if"isDisabled" :underline"false" type"pr…

【C语言】程序员自我修养之文件操作

【C语言】程序员自我修养之文件操作 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C语言学习之路 文章目录 【C语言】程序员自我修养之文件操作前言一.文件介绍1.1为什么使用文件1.2文件分类1.3二进制文件和文本文件 二.文件的打开和关闭2.…

桌面藏线大法

1有线改无线&#xff1a; 蓝牙鼠标 蓝牙键盘 蓝牙耳机 2将排插贴到桌子底下 购物软件上搜 3断舍离 不要的电子产品统统扔掉 4 洞洞板和挂钩 这个不用介绍了

暴雨信息液冷计算解决方案亮相CCIG 2024

5月24日&#xff0c;2024中国图象图形大会&#xff08;CCIG&#xff09;在陕西西安正式开幕。作为涵盖图像图形各专业领域的综合性的全国性学术会议&#xff0c;CCIG面向开放创新、交叉融合的发展趋势&#xff0c;为图像图形相关领域的专家学者和产业界的同仁&#xff0c;搭建了…

Java+Spring+ MySQL + MyCat云HIS有哪些优势?智慧医疗云(HIS)低成本与安全保障的完美结合

JavaSpring MySQL MyCat云HIS有哪些优势&#xff1f;智慧医疗云(HIS)低成本与安全保障的完美结合 云HIS的优点包括节省成本、便捷高效、稳妥安全等。通过云HIS&#xff0c;医疗机构无需在本地建立机房、购买服务器和应用软件&#xff0c;降低了硬件和人力成本。同时&#xff0…