PO模式简介

V1顺序型:不能批量运行

import unittest
from selenium import webdriver
from time import sleep
driver = webdriver.Edge()# driver.maximize_window()
driver.implicitly_wait(30)
# driver.get(r"https://demo5.tp-shop.cn/")
# driver.find_element_by_partial_link_text("登录").click()driver.get("https://demo5.tp-shop.cn/Home/user/login.html")driver.find_element_by_css_selector("#username").send_keys("15217578333")driver.find_element_by_css_selector("#password").send_keys("123456")driver.find_element_by_css_selector("#verify_code").send_keys("AUWR")
driver.find_element_by_css_selector(".J-login-submit").click()
msg = driver.find_element_by_css_selector(".layui-layer-content").text
print(msg)
assert "账号不存在" == msg
driver.find_element_by_css_selector(".layui-layer-btn0").click()
sleep(2)
driver.quit()
assert "密码不存在" == msg
driver.find_element_by_css_selector(".layui-layer-btn0").click()
sleep(2)
driver.quit()

Unittest:代码冗余 业务脚本与页面对象没有分开

import unittest
from selenium import webdriver
from time import sleepclass TestLogin(unittest.TestCase):driver = Nonedef tearDown(self):self.driver.refresh()@classmethoddef setUpClass(cls):cls.driver = webdriver.Edge()# driver.maximize_window()cls.driver.implicitly_wait(30)# cls.driver.get(r"https://demo5.tp-shop.cn/")# cls.driver.find_element_by_partial_link_text("登录").click()cls.driver.get(r"https://demo5.tp-shop.cn/Home/user/login.html")@classmethoddef tearDownClass(cls):sleep(2)cls.driver.quit()def test_login_username_not_exist(self):driver = self.driverdriver.find_element_by_css_selector("#username").send_keys("15217578333")driver.find_element_by_css_selector("#password").send_keys("123456")driver.find_element_by_css_selector("#verify_code").send_keys("AUWR")driver.find_element_by_css_selector(".J-login-submit").click()msg = driver.find_element_by_css_selector(".layui-layer-content").textprint(msg)try:self.assertEqual("用户不存在", msg)driver.find_element_by_css_selector(".layui-layer-btn0").click()except AssertionError:self.driver.get_screenshot_as_file("../image/not_exist.png")# raisedef test_login_password_err(self):driver = self.driverdriver.find_element_by_css_selector("#username").send_keys("15217578333")driver.find_element_by_css_selector("#password").send_keys("123456")driver.find_element_by_css_selector("#verify_code").send_keys("AUWR")driver.find_element_by_css_selector(".J-login-submit").click()msg = driver.find_element_by_css_selector(".layui-layer-content").textprint(msg)try:self.assertEqual("密码错误",msg)driver.find_element_by_css_selector(".layui-layer-btn0").click()except AssertionError:self.driver.get_screenshot_as_file("../image/error.png")# raise

V3 PO page object 冗余代码 耦合性太强

#pagefrom selenium import webdriverclass PageLogin:def __init__(self):self.driver = webdriver.Edge()# driver.maximize_window()self.driver.implicitly_wait(30)# driver.get(r"https://demo5.tp-shop.cn/")# driver.find_element_by_partial_link_text("登录").click()self.driver.get(r"https://demo5.tp-shop.cn/Home/user/login.html")# 点击登录def page_click_login_link(self):pass# 输入用户名def page_input_username(self,username):self.driver.find_element_by_css_selector("#username").send_keys(username)# 输入密码def page_input_pwd(self,password):self.driver.find_element_by_css_selector("#password").send_keys(password)# 输入验证码def page_input_vertify_code(self,code):self.driver.find_element_by_css_selector("#verify_code").send_keys(code)# 点击登录def page_click_login_btn(self):self.driver.find_element_by_css_selector(".J-login-submit").click()# 获取异常提示信息def page_get_text(self):return self.driver.find_element_by_css_selector(".layui-layer-content").text# 点击提示框确认按钮def page_click_err_btn_ok(self):self.driver.find_element_by_css_selector(".layui-layer-btn0").click()# 组装业务登录方法、给业务层调用def page_login(self,username,password,code):self.page_click_login_link()self.page_input_username(username)self.page_input_pwd(password)self.page_input_vertify_code(code)self.page_click_login_btn()
#业务层
import unittest
from v3.page.page_login import PageLogin
from  parameterized import parameterized
from time import sleep
class TestLogin(unittest.TestCase):def setUp(self):# 获取登录页面对象self.login = PageLogin()def tearDown(self):self.login.driver.quit()@parameterized.expand([("13822223333","123456","8888","账号不存在"),("13822223333","1236","8888","密码错误")])def test_login(self,username,password,code,expect):self.login.page_login(username,password,code)msg = self.login.page_get_text()try:self.assertEqual(expect,msg)self.login.page_click_err_btn_ok()except AssertionError:self.login.driver.get_screenshot_as_file("../../image/login_error%s.png" % (time.strftime("%Y_%m_%d %H_%M_%S")))# raise

PO page object 页面 对象

V4 三层结构 base page scripts

base(基类)page页面中一些公共的方法 即抽取公共方法放到base中 (提取方法)

新建Base类 初始化方法 查找元素方法 点击元素方法 输入方法 获取文本方法 截图方法(调用数据)

page(页面对象)一个页面封装成一个对象 通过继承base类 使用其中的公共方法(实现使用)

scripts(业务层 脚本层 )导包调用page页面

from selenium.webdriver.common.by import By
loc = (By.CSS_SELECTOR,".telA")
# loc = By.CSS_SELECTOR,".telA" 也是元组类型
# driver.find_element(By.CSS_SELECTOR,".telA")
print(loc)
# 解包
print(*loc)# ('css selector', '.telA')
# css selector .telA

包和文件夹 包多了init文件

# base
from selenium.webdriver.support.wait import WebDriverWait
import time
from selenium import webdriver
class Base:# 临时替代# def __init__(self, driver):#     self.driver = driverdef __init__(self):self.driver = webdriver.Edge()self.driver.get(r"https://demo5.tp-shop.cn/")# 解包只需一次 driver传入即可 loc就是查找元素使用的# 查找元素方法(提供:点击,输入,获取文本)使用def base_find_element(self, loc,timeout=30,poll=0.5):  # loc 元组 *loc进行解包# 显示等待return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(lambda x: x.find_element(*loc))# 点击方法 调用时只需要输入点击哪个元素def base_click(self,loc):self.base_find_element(loc).click()# 输入方法 调用时只需要两个参数 哪个元素 输什么内容def base_input(self,loc,value):el = self.base_find_element(loc)el.clear()el.send_keys(value)# 获取文本方法 哪个元素文本def base_get_text(self,loc):# 一定要返回元素的文本信息return self.base_find_element(loc).text# 截图方法def base_get_image(self):self.driver.get_screenshot_as_file("../../image/login_error%s.png" % (time.strftime("%Y_%m_%d %H_%M_%S")))
# page init
from selenium.webdriver.common.by import By# 登录页面元素配置信息 临时存放地
# 登录链接
login_link = By.PARTIAL_LINK_TEXT, "登录"
# 用户名
login_username = By.ID, "username"
# 密码
login_password = By.ID, "password"
# 验证码
login_verify = By.ID, "verify_code"
# 登录按钮
login_btn = By.CSS_SELECTOR, ".J-login-submit"
# 获取异常文本信息
login_err = By.CSS_SELECTOR, ".layui-layer-content"
# 点击异常提示框文本按钮
login_err_btn_ok = By.CSS_SELECTOR, ".layui-layer-btn0"
#page page_login
from v4 import page
from v4.base.base import Baseclass PageLogin(Base):# 点击登录按钮def page_click_login_lin(self):self.base_click(page.login_link)# 输入用户名def page_input_username(self,username):self.base_input(page.login_username,username)# 输入密码def page_input_password(self,password):self.base_input(page.login_password,password)# 输入验证码def page_input_vertfy_code(self,code):self.base_input(page.login_verify,code)# 点击登录按钮def page_click_login_btn(self):self.base_click(page.login_btn)# 获取提示框文本信息def page_get_err_info(self):return self.base_get_text(page.login_err)# 点击提示框确定按钮def page_click_err_btn_ok(self):self.base_click(page.login_err_btn_ok)# 截图def page_get_image(self):self.base_get_image()# 组装业务登录方法、给业务层调用def page_login(self,username,password,code):self.page_input_username(username)self.page_input_password(password)self.page_input_vertfy_code(code)self.page_click_login_btn()
# scripts 业务层import unittest
from v4.page.page_login import PageLogin
from selenium import webdriver
from parameterized import parameterizeddef get_data():return [("13822223333","123456","8888","账号不存在"),("13822223333","1236","8888","密码错误")]class Test_login(unittest.TestCase):login = None@classmethoddef setUpClass(cls):cls.login = PageLogin()cls.login.page_click_login_lin()@classmethoddef tearDownClass(cls):cls.login.driver.quit()def tearDown(self):self.login.driver.refresh()@parameterized.expand(get_data())def test_login(self,username,password,code,expect):self.login.page_login(username,password,code)msg = self.login.page_get_err_info()try:self.assertEqual(expect,msg)self.login.page_click_err_btn_ok()except AssertionError:self.login.page_get_image()# raise

单例模式:无论实例化多少对象 获取的同一个对象

用处:获取浏览器 都是一个

PO模式分层:面向对象思想 对象库层 操作层 业务层

就是进行三层代码的封装

列表也行 就是麻烦一点 list[0] list[1] 元组直接解包即可

dumps带s时转换 不带s是写json
dumps() 将字典转换成json字符串
json中dump()写入json
loads() 将字符串转为字典
load() 读取json方法
import json# 将字典转换为json字符串data = {"name":"小明","age":18}
print(type(data)) # <class 'dict'>data = json.dumps(data)
print(type(data)) # <class 'str'>print(data)
# {"name": "\u5c0f\u660e", "age": 18} 序列化# 将字符串转为json
data = '{"name":"小明","age":18}' #属性:双引号
print(type(data)) # <class 'str'>data = json.loads(data)
print(type(data)) # <class 'dict'>print(data) # {'name': '小明', 'age': 18}  变成单引号了

JSON文件读写

ctrl+p 查看需要参数

加法测试项目V4PO加数据驱动

Base

base.py Base

from selenium import webdriver
from case_add import pageclass GetDriver:# 设置类属性driver = None# 获取driver@classmethoddef get_driver(cls):if cls.driver is None:# 实例化浏览器cls.driver = webdriver.Edge()# 最大化cls.driver.maximize_window()# 打开浏览器cls.driver.get(page.url)return cls.driver@classmethoddef quit_driver(cls):if cls.driver:print("关闭之前:", cls.driver)cls.driver.quit()print("关闭之后:", cls.driver)cls.driver = Noneprint("置空之后:", cls.driver)if __name__ == '__main__':# 第一次获取浏览器print(GetDriver().get_driver())# 第二次获取浏览器print(GetDriver().get_driver())# 调用关闭,测试 关闭后driver是否为NoneGetDriver().quit_driver()print(GetDriver().get_driver())

虽然是同一个浏览器网址 但是将driver置空后

每次获取浏览器是一个全新的浏览器实例

为了确保在下次获取浏览器时可以重新实例化一个新的浏览器对象,而不是继续使用之前关闭的浏览器对象。

from selenium.webdriver.support.wait import WebDriverWait
import timeclass Base:# 初始化方法def __init__(self, driver):self.driver = driver# 查找元素def base_find_element(self, loc, timeout=30, poll=0.5):""":param loc:  元素的定位信息,格式为元祖:param timeout: 默认超时时间30秒:param poll: 访问频率,默认0.5查找一次元素:return: 返回查找到的元素"""# 显示等待return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(lambda x: x.find_element(*loc))# 点击def base_click(self, loc):self.base_find_element(loc).click()# 获取value属性方法封装def base_get_element_text(self, loc):# 使用get_attribute()方法获取指定的元素属性值# 注意:返回return self.base_find_element(loc).get_attribute("value")# 截图def base_get_screen_shot(self):self.driver.get_screenshot_as_file("../../image/{}.png".format(time.strftime("%Y_%m_%d %H_%M_%S")))

Page

init.py

from selenium.webdriver.common.by import By"""以下为服务器域名配置地址"""
url = r"http://cal.apple886.com/""""以下为计算器配置数据"""
# number = By.CSS_SELECTOR,"#simple{}"calc_add = By.CSS_SELECTOR,"#simpleAdd"
calc_equal = By.CSS_SELECTOR,"#simpleEqual"
calc_get_result = By.CSS_SELECTOR,"#resultIpt"
calc_clear = By.CSS_SELECTOR,"#simpleClearAllBtn"
num = "12345342"for i in num:print("simple{}".format(i))
Page_calc.py 继承Base

PageCalc

from selenium.webdriver.common.by import By
from case_add.base.base import Base
from case_add import pageclass PageCalc(Base):def page_num_click(self, num):for i in str(num):loc = By.CSS_SELECTOR, "#simple{}".format(i)self.base_click(loc)def page_add_btn(self):self.base_click(page.calc_add)def page_equal_btn(self):self.base_click(page.calc_equal)def page_get_result(self):return self.base_get_element_text(page.calc_get_result)def page_clear(self):self.base_click(page.calc_clear)def page_get_screen_shot(self):self.base_get_screen_shot()def page_calc(self, num1, num2):self.page_num_click(num1)self.page_add_btn()self.page_num_click(num2)self.page_equal_btn()

数据驱动

import jsondef read_json(filename):filepath = "../data/"+ filenamewith open(filepath,"r",encoding="utf-8") as f:return json.load(f)if __name__ == '__main__':data = read_json("calc.json")# print(data)# print("---" * 50)list1 = []for i in data.values():list1.append((i.get('a'),i.get('b'),i.get('expect')))print(list1)

业务层

import unittest
from case_add.tool.read_json import read_json
from case_add.base.get_driver import GetDriver
from case_add.page.page_calc import PageCalc
from parameterized import parameterizeddef get_data():data = read_json("calc.json")arr = []for i in data.values():arr.append((i.get('a'), i.get('b'), i.get('expect')))return arrclass TestCal(unittest.TestCase):driver = None@classmethoddef setUpClass(cls):cls.driver = GetDriver.get_driver()cls.calc = PageCalc(cls.driver)@classmethoddef tearDownClass(cls):GetDriver.quit_driver()@parameterized.expand(get_data())def test_calc(self,num1,num2,expect):self.calc.page_calc(num1,num2)result = self.calc.page_get_result()try:self.assertEqual(str(expect),str(result))self.calc.page_clear()except AssertionError:self.calc.base_get_screen_shot()raise

正向和逆向用例是在软件测试中常用的概念。正向用例是使用软件时的预期行为,即用户按照设计好的流程和功能来操作软件系统,以测试系统是否按照预期的方式工作。而逆向用例则是用来测试系统对不符合预期情况的处理能力,即人为制造一些异常情况或错误操作,看系统如何响应。

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

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

相关文章

Python 获取tiktok视频评论回复数据 api接口

TIKTOK api接口 用于爬取tiktok视频评论回复数据 详细采集页面如图 https://www.tiktok.com/dailymail/video/7329872821990182190?qneural%20link&t1706783508149 请求API http://api.xxxx.com/tt/video/info/comment/reply?video_id7288909913185701125&comment_…

【C++】指针的点运算与箭头运算(->)的奥秘与应用

在编程的世界里&#xff0c;指针作为连接程序与内存之间的桥梁&#xff0c;扮演着至关重要的角色。对于使用C、C等语言进行开发的程序员而言&#xff0c;理解并掌握指针的使用技巧是提升编程能力的必经之路。其中&#xff0c;指针的点运算&#xff08;.&#xff09;和箭头运算&…

Android系统集成和使用FFmpeg

文章目录 前言FFmpeg源码下载交叉编译NDK下载x264编译源码下载编译 FFmpeg编译脚本 AOSP继承FFmpeg 前言 原生AOSP中并未继承FFmpeg&#xff0c;所以要想在android上使用&#xff0c;需要自己编译集成。 FFmpeg源码下载 git clone https://git.ffmpeg.org/ffmpeg.git目前最新…

自动化测试报告pytest-html样式美化

最近我将 pytest-html 样式优化了 一版 先看优化前&#xff1a; 优化后&#xff1a; 优化内容包括&#xff1a; 删除部分多余字段新增echart图表部分字体大小、行间距、颜色做了美化调整运行环境信息移至报告最后部分字段做了汉化处理&#xff08;没全部翻译是因为&#xf…

vue3 引入百度地图的三种方式

本次也是正好写了一个基于VUE3和百度地图的设计&#xff0c;但奈何第一次使用百度地图&#xff0c;在学习的途中遇到了很多问题&#xff0c;也发现网上的材料相对较少&#xff0c;因此做出了一些小总结&#xff0c;后续还会更新。 一、直接引入 直接在public中的index.html中进…

[FreeRTOS 功能应用] 事件组 功能应用

文章目录 一、基础知识点二、代码讲解三、结果演示四、代码下载 一、基础知识点 [FreeRTOS 基础知识] 事件组 概念 [FreeRTOS 内部实现] 事件组 本实验是基于STM32F103开发移植FreeRTOS实时操作系统&#xff0c;事件组实战操作。(当task1和task2同时完成&#xff0c;才执行ta…

二维Gamma分布的激光点云去噪

目录 1、Gamma 分布简介2、实现步骤 1、Gamma 分布简介 Gamma 分布在合成孔径雷达( Synthetic Aperture &#xff32;adar&#xff0c;SA&#xff32;) 图像分割中具有广泛应用&#xff0c;较好的解决了SA&#xff32; 图像中相干斑噪声对图像分割的影响。采用二维Gamma 分布对…

web前端开发——开发环境和基本知识

今天我来针对web前端开发讲解一些开发环境和基本知识 什么是前端 前端通常指的是网站或者Web应用中用户可以直接与之交互的部分&#xff0c;包括网站的结构、设计、内容和功能。它是软件开发中的一个专业术语&#xff0c;特别是指Web开发领域。前端开发涉及的主要技术包括HTML…

昇思25天学习打卡营第15天|linchenfengxue

Pix2Pix实现图像转换 Pix2Pix概述 Pix2Pix是基于条件生成对抗网络&#xff08;cGAN, Condition Generative Adversarial Networks &#xff09;实现的一种深度学习图像转换模型&#xff0c;该模型是由Phillip Isola等作者在2017年CVPR上提出的&#xff0c;可以实现语义/标签到…

Java常用算法集合扩容机制分析

基础篇 基础篇要点&#xff1a;算法、数据结构、基础设计模式 1. 二分查找 要求 能够用自己语言描述二分查找算法能够手写二分查找代码能够解答一些变化后的考法 算法描述 前提&#xff1a;有已排序数组 A&#xff08;假设已经做好&#xff09; 定义左边界 L、右边界 R&…

东芝TB6560AHQ/AFG步进电机驱动IC:解锁卓越的电机控制性能

作为一名工程师&#xff0c;一直在寻找可靠且高效的组件来应用于你的项目中。东芝的TB6560AHQ/AFG步进电机驱动IC能够提供精准且多功能的电机控制&#xff0c;完全符合现代应用的高要求&#xff0c;保证高性能和易用性。在这篇文章中&#xff0c;我们将探讨TB6560AHQ/AFG的主要…

硅纪元视角 | 国内首款鸿蒙人形机器人“夸父”开启应用新篇章

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

es6新语法

es6新语法 1 什么是ES6 JS语法分三块 ECMAScript : 基础语法BOM 浏览器对象 history location windowDOM 文档对象 document 编程语言JavaScript是ECMAScript的实现和扩展 。ECMAScript是由ECMA&#xff08;一个类似W3C的标准组织&#xff09;参与进行标准化的语法规范。ECMAS…

医疗器械企业CRM系统推荐清单(2024版)

近年来&#xff0c;我国医疗器械行业在国家政策支持、医改深入、人口老龄化和消费能力提升等因素推动下&#xff0c;得到了快速发展&#xff0c;正日益成为创新能力增强、市场需求旺盛的朝阳产业。然而&#xff0c;行业也面临价格压力、市场份额重新分配、合规风险以及产品和服…

解决 MEX 文件 ‘xxx.mexw64‘ 无效: 找不到指定的模块。的问题

1.问题描述 在matlab R2021b中运行编译好后的gptoolbox工具箱中的函数[SVtemp,SFtemp,IF] selfintersect(V,F);报错如下 MEX 文件 E:\MATLAB_File\gptoolbox\mex\selfintersect.mexw64 无效: 找不到指定的模块。出错 offset_bunny (第 15 行) [SVtemp,SFtemp,IF] selfinter…

论文略读:Learning and Forgetting Unsafe Examples in Large Language Models

随着发布给公众的大语言模型&#xff08;LLMs&#xff09;数量的增加&#xff0c;迫切需要了解这些模型从第三方定制的微调数据中学习的安全性影响。论文研究了在包含不安全内容的噪声定制数据上微调的LLMs的行为&#xff0c;这些数据集包含偏见、毒性和有害性 发现虽然对齐的L…

3033. 修改矩阵 Easy

给你一个下标从 0 开始、大小为 m x n 的整数矩阵 matrix &#xff0c;新建一个下标从 0 开始、名为 answer 的矩阵。使 answer 与 matrix 相等&#xff0c;接着将其中每个值为 -1 的元素替换为所在列的 最大 元素。 返回矩阵 answer 。 示例 1&#xff1a; 输入&#xff1a;…

查看电脑显卡(NVIDIA)应该匹配什么版本的CUDA Toolkit

被串行计算逼到要吐时&#xff0c;决定重拾CUDa了&#xff0c;想想那光速般的处理感觉&#xff08;夸张了&#xff09;不要太爽&#xff0c;记下我的闯关记录。正好我的电脑配了NVIDIA独显&#xff0c;GTX1650&#xff0c;有菜可以炒呀&#xff0c;没有英伟达的要绕道了。回到正…

【Linux】生物信息学常用命令

参考资料来自生信技能树 先输入echo export PS1"[\033]2;\h:\u \w\007\033[33;1m]\u \033[35;1m\t\033[0m [\033[36;1m]\w[\033[0m]\n[\e[32;1m]$ [\e[0m]" >> ~/.bashrc 再输入source ~/.bashrc就能够让命令字体带上颜色&#xff0c;同时命令将会在下一行开…

软件设计之Java入门视频(12)

软件设计之Java入门视频(12) 视频教程来自B站尚硅谷&#xff1a; 尚硅谷Java入门视频教程&#xff0c;宋红康java基础视频 相关文件资料&#xff08;百度网盘&#xff09; 提取密码&#xff1a;8op3 idea 下载可以关注 软件管家 公众号 学习内容&#xff1a; 该视频共分为1-7…