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

关于Selenium的网页对象单元测试的设计模式

写在前面:经过了实践总结一下经验,心得进行一个分享。


首先driver是可以单独抽出来的,变成一个driver函数放在driver.py。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Optionsdef get_chrome_driver():# 启动driveroptions = Options()# 替换为你本地的Chromed路径options.binary_location = r"D:\software\Chrome-bin\chrome.exe"# 替换为你本地的Chromedriver路径chromedriver_path = r'D:\software\Chrome-bin\chromedriver.exe'# 使用Service对象指定Chromedriver路径service = Service(chromedriver_path)driver = webdriver.Chrome(service=service, options=options)return driver

然后我们新建page.py,在这里我们只处理页面的对象,因此我们创建页面类在此,当然这个页面类需要和HTML元素和驱动进行组合才能形成一个页面。

我们创建BasePage,以后的页面类都用它作为基类。首先是传一个驱动,组合起来

class BasePage(object):"""Base class to initialize the base page that will be called from allpages"""def __init__(self, driver):self.driver = driverclass LoginPage(BasePage):def __init__(self, driver):super().__init__(driver)

接着我们在element.py创建元素的基类,以后的元素类都继承自它

from selenium.webdriver.support.ui import WebDriverWaitclass BaseElement(object):"""Base page class that is initialized on every page object class."""locator = Nonedef __set__(self, obj, value):"""Sets the text to the value supplied"""driver = obj.driverWebDriverWait(driver, 5).until(lambda dri: dri.find_element(*self.locator))driver.find_element(*self.locator).clear()driver.find_element(*self.locator).send_keys(value)def __get__(self, obj, owner):"""Gets the specified element object"""driver = obj.driverWebDriverWait(driver, 5).until(lambda dri: dri.find_element(*self.locator))self.element = driver.find_element(*self.locator)return self.elementdef click(self):self.element.click()def get_text(self):return self.element.get_attribute("value")

接着我们在locator.py创建定位器类,没什么特别,就是作为一个类似字典的静态类存放元素的位置

from selenium.webdriver.common.by import Byclass LonginPageLocators(object):"""A class for login page locators. All login page locators should come here"""basic_username = (By.ID, 'basic_username')basic_password = (By.ID, 'basic_password')details_button = (By.ID, 'details-button')proceed_link = (By.ID, 'proceed-link')login_button = (By.ID, 'submitBtn')

准备工作就绪,那么我们来编写LoginPage吧~
首先组合我们需要的HTML元素,然后编写一个login业务函数进行业务处理。


class BasePage(object):"""Base class to initialize the base page that will be called from allpages"""def __init__(self, driver):self.driver = driverclass LoginPage(BasePage):def __init__(self, driver):super().__init__(driver)class DetailButtonElement(BaseElement):locator = LonginPageLocators.details_buttonclass ProceedLinkElement(BaseElement):locator = LonginPageLocators.proceed_linkclass UsernameTextElement(BaseElement):locator = LonginPageLocators.basic_usernameclass PasswordTextElement(BaseElement):locator = LonginPageLocators.basic_passwordclass LoginButtonElement(BaseElement):locator = LonginPageLocators.login_buttonclass RankBoxElement(BaseElement):locator = LonginPageLocators.rank_boxdetail_button_ele = DetailButtonElement()proceed_link_ele = ProceedLinkElement()username_text_ele = UsernameTextElement()password_text_ele = PasswordTextElement()login_button_ele = LoginButtonElement()rank_box_ele = RankBoxElement()def login(self):self.detail_button_ele.click()self.proceed_link_ele.click()self.username_text_ele = 'admin'self.password_text_ele = '123456'self.login_button_ele.click()_ = self.rank_box_ele  # just test web is complete

_ = self.rank_box_ele小细节是用来测试是否进入主页面的。

回到单元测试.py添加测试函数,debug运行。

    def test_login(self):login_page = page.LoginPage(self.driver)login_page.login()

当我们登录成功后,我们就可以跳转到我们需要页面,进行脚本处理。当然了进入了新的页面,别忘了创建新的页面类。在我的例子中就是创建了新的页面类ResourceDetailPage以便完成后续的业务。

    def test_turn_to_resource(self):self.test_login()# 页面跳转self.driver.get("https://127.0.0.1:38000/#/resource/detail/3668")def test_resource_delete(self):self.test_turn_to_resource()# 创建新的page对象resource_detail_page = page.ResourceDetailPage(self.driver)# 在新的page处理业务...resource_detail_page.while_delete()

相关文章:

关于Selenium的网页对象单元测试的设计模式

写在前面:经过了实践总结一下经验,心得进行一个分享。 首先driver是可以单独抽出来的,变成一个driver函数放在driver.py。 from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver…...

基于多反应堆的高并发服务器【C/C++/Reactor】(上)

(一)初始化服务器端用于监听的套接字 Server.h #pragma once // 初始化监听的套接字 int initListenFd(unsigned short port); Server.c int initListenFd(unsigned short port) {// 1.创建监听的fdint lfd socket(AF_INET, SOCK_STREAM, 0);if(lf…...

腾讯云debian服务器的连接与初始化

目录 1. 远程连接2. 软件下载3. 设置开机自启动 1. 远程连接 腾讯云给的服务器在安装好系统之后,只需要在防火墙里面添加一个白名单(ip 或者域名)就能访问了。 浏览器打开https://www.ipip.net/,在左下角找到自己所用的WIFI的公…...

医保购药小程序:智能合约引领医疗数字革新

在医疗领域,医保购药小程序通过引入智能合约技术,为用户提供更为高效、安全的购药体验。本文将通过简单的智能合约代码示例,深入探讨医保购药小程序如何利用区块链技术中的智能合约,实现医保结算、购药监控等功能,为医…...

神经网络:深度学习优化方法

1.有哪些方法能提升CNN模型的泛化能力 采集更多数据:数据决定算法的上限。 优化数据分布:数据类别均衡。 选用合适的目标函数。 设计合适的网络结构。 数据增强。 权值正则化。 使用合适的优化器等。 2.BN层面试高频问题大汇总 BN层解决了什么问…...

Unity中Shader旋转矩阵(二维旋转矩阵)

文章目录 前言一、旋转矩阵的原理1、我们以原点为中心,旋转坐标轴θ度2、求 P~2x~:3、求P~2y~:4、最后得到 P~2~点 的点阵5、该点阵可以拆分为以下两个矩阵相乘的结果 二、在Shader中,使用该旋转矩阵实现围绕 z 轴旋转1、在属性面板定义 floa…...

前端面试题(计算机网络):options请求方法及使用场景

OPTIONS请求方法及使用场景 回答思路:什么是options请求-->options请求方法-->options使用场景什么是options请求?(浅入)扩展:常见的HTTP请求有什么?扩展:常见的HTTP请求的作用&#xff1…...

使用docker-compose管理docker服务

使用docker-compose管理docker服务 1,创建docker-compose.yml version: 3 services:javaapp:build: context: ./javaappdockerfile: Dockerfileports:- "9202:9202"- "19202:19202"goapp:build: context: ./goappdockerfile: Dockerfileports…...

Python_Tkinter和OpenCV模拟行星凌日传输光度测定

传输光度测定 在天文学中,当相对较小的天体直接经过较大天体的圆盘和观察者之间时,就会发生凌日。 当小物体移过较大物体的表面时,较大物体会稍微变暗。 最著名的凌日是水星和金星对太阳的凌日。 借助当今的技术,天文学家可以在…...

【安全】使用auparse解析auditd审计日志

使用auparse解析auditd审计日志 1 审计日志特点 查看auditd.log的日志,审计日志的格式如下: typeSYSCALL msgaudit(1703148319.954:11680975): archc000003e syscall2 successyes exit5 a01102430 a10 a21b6 a324 items1 ppid7752 pid7761 auid0 uid0…...

flink watermark 实例分析

WATERMARK 定义了表的事件时间属性,其形式为: WATERMARK FOR rowtime_column_name AS watermark_strategy_expression rowtime_column_name 把一个现有的列定义为一个为表标记事件时间的属性。该列的类型必须为 TIMESTAMP(3)/TIMESTAMP_LTZ(3),且是 sche…...

系列十二(面试)、Java中的GC回收类型有哪些?

一、Java中的GC回收类型 1.1、概述 Java中的GC回收类型主要包含以下几种,即:UseSerialGC、UseParallelGC、UseConcMarkSweepGC、UseParNewGC、UseParallelOldGC、UseG1GC。 1.2、源码...

华为数通方向HCIP-DataCom H12-831题库(多选题:201-220)

第201题 在多集群RR组网中,每个集群中部署了一台RR设备及其客户机,各集群的RR与为非客户机关系,并建立IBGP全连接。以下关于BGP路由反射器发布路由规则的描述,正确的有哪些? A、若某RR从EBGP对等体学到的路由,此RR会传递给其他集群的RR B、若某RR从非客户机IBGP对等体学…...

NLP论文阅读记录 - | 使用GPT对大型文档集合进行抽象总结

文章目录 前言0、论文摘要一、Introduction二.相关工作2.1Summarization2.2 神经网络抽象概括2.2.1训练和测试数据集。2.2.2 评估。 2.3 最先进的抽象摘要器 三.本文方法3.1 查询支持3.2 文档聚类3.3主题句提取3.4 语义分块3.5 GPT 零样本总结 四 实验效果4.1数据集4.2 对比模型…...

华为全屋wifi6蜂鸟套装标准

华为政企42 华为政企 目录 上一篇华为安防监控摄像头下一篇华为企业级无线路由器...

系列二十八、如何在Oracle官网下载JDK的api文档

一、官网下载JDK的api文档 1.1、官网地址 https://www.oracle.com/java/technologies/javase-jdk21-doc-downloads.html 1.2、我分享的api.chm 链接:https://pan.baidu.com/s/1Bf55Fz-eMTErmQDtZZcewQ?pwdyyds 提取码:yyds 1.3、参考 https://ww…...

STM32-ADC模数转换器

目录 一、ADC简介 二、逐次逼近型ADC内部结构 三、STM32内部ADC转换结构 四、ADC基本结构 五、输入通道 六、转换模式 6.1单次转换,非扫描模式 6.2连续转换,非扫描模式 6.3单次转换,扫描模式 6.4连续转换,扫描模式 七、…...

谷歌手机安装证书到根目录

1、前提你已经root,安装好面具 2,下载movecert模块,自动帮你把证书从用户证书移动成系统证书 视频教程,手机为谷歌手机 https://www.bilibili.com/video/BV1pG4y1A7Cj?p11&vd_source9c0a32b00d6d59fecae05b4133f22f06 软件下…...

代码随想录 322. 零钱兑换

题目 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无限的。…...

【图的应用二:最短路径】- 用 C 语言实现迪杰斯特拉算法和弗洛伊德算法

目录 一、最短路径 二、迪杰斯特拉算法 三、弗洛伊德算法 一、最短路径 假若要在计算机上建立一个交通咨询系统,则可以采用图的结构来表示实际的交通网络。如下图所示,图中顶点表示城市,边表示城市间的交通联系。 这个咨询系统可以回答旅…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...