【web自动化】-5- fixture集中管理和项目重构

一、投标用例设计 

# 定义让前台页面保持自动登录的fixture
@pytest.fixture()
def user_driver():driver = webdriver.Chrome()driver.get("http://47.107.116.139/fangwei/")driver.maximize_window()# 创建页面类对象page = ReceptionLoginPage(driver)# 通过页面类对象调用方法执行脚本msg = page.login("admin", "msjy123")# 断言实际结果print(msg)assert msg == "成功登录"return driver
  • 如何绕过登录执行投标用例流程,包括投标的正例和反例
  • 在浏览器的驱动第一次执行前台页面登录之后,保持登录状态,在第二次及以上的用例执行投标
定义一个 fixture
  • 完成第一次登录之后进行清除页面缓存
@pytest.fixture()
# 清除缓存的夹具,可以结合第一次登录成功之后的夹具一起结合使用
def clear_deal_page(user_driver):user_driver.get("http://47.107.116.139/fangwei/index.php?ctl=deal&id=25070")
  • 在投标用例中使用清除缓存的 fixture

出现的问题:可以正常流程去登录,但是定位点击马上投标的元素超时

  • 元素找不到
  • 问题出现原因:登录成功之后,界面没有立马出现马上投标元素
def test_user_deal_ok(user_driver, clear_deal_page):# 投标用例执行page = ReceptionLoginPage(user_driver)msg = page.pay("msjy123")print(msg)assert msg == "投标成功!"def test_user_deal_ok2(user_driver, clear_deal_page):# 投标用例执行page = ReceptionLoginPage(user_driver)msg = page.pay("msjy123")print(msg)assert msg == "投标成功!"def test_user_deal_fail(user_driver, clear_deal_page):# 投标用例执行page = ReceptionLoginPage(user_driver)msg = page.pay("msjy1234")print(msg)assert msg == "支付密码错误"

 

  • 由于直接进入投标界面可以实现流程用例执行
  • 解决方案:
    • 由于登录成功之后自动跳转立即投资界面

    • 所以注释点击马上投标的元素

    • 保持登录的夹具: user_driver 作用域改成 session 级别,保持整个页面的自动登录状态

最终结果:

  • 实现投标用例在第一次登录成功之后,不需要继续进行登录,直接执行投标流程用例即可
  • 作用:保持第一次之后的登录状态来完成投标流程用例执行
# 定义用例脚本执行投标步骤:
def pay(self, password):# - 点击马上投标按钮# self.find_element(*self.btn_deal_submit).click()# - 点击立即投资self.find_element(*self.btn_money).click()# - 输入支付密码self.find_element(*self.ipt_pay_password).send_keys(password)# - 点击确定按钮self.find_element(*self.btn_pay_submit).click()# 获取提示信息的实际结果断言预期结果msg = self.find_element(*self.pay_msg, need_wait=True).text# - 关闭提示信息弹框self.find_element(*self.txt_deal_msg).click()# 返回用例执行结果msgreturn msg

1. Fixture 作用域控制(scope="session"

如果 user_driver Fixture 定义时指定了 scope="session"(需补充代码确认,但从场景推断是关键),它会在整个测试会话期间只执行一次

@pytest.fixture(scope="session")  # 关键:作用域为 session,全局共享
def user_driver():driver = webdriver.Chrome()# 登录逻辑...return driver

  • scope="session" 意味着:整个测试运行中,user_driver 只会初始化一次浏览器、执行一次登录,所有依赖它的用例共享同一个浏览器实例,不会重复打开新窗口。

2. 保持登录状态(Cookie/Session 复用)

Web 登录本质是通过 Cookie 或 Session 维持状态:

  • 首次用例执行时,user_driver 完成登录,浏览器会缓存登录态 Cookie。
  • 后续用例复用同一个 driver 实例时,浏览器自带已登录的 Cookie,访问系统时会自动识别登录状态,无需重复登录。

3. 用例依赖共享实例

测试用例通过参数注入 user_driver,所有用例拿到的是同一个浏览器对象

def test_bid_2(user_driver, clear_deal_page):# 复用已登录的 user_driver,无需重新打开窗口/登录page = ReceptionLoginPage(user_driver)  page.pay(...)

因为浏览器实例没销毁,登录状态、页面上下文都被保留,自然 “跳过登录、不新开窗口”。

关键总结

  • Fixture 作用域(session 让浏览器实例全局复用,避免重复初始化。
  • Cookie 持久化 让登录状态在同浏览器实例内自动延续。
  • 最终实现 “一次登录、多例复用”,跳过重复登录和窗口打开流程。

 

在自动化测试流程里,user_driver 结合 clear_deal_page 主要是为了 解决 “登录后页面状态残留” 导致的用例干扰问题

1. 「页面缓存 / 残留状态」的干扰问题

登录后执行投标用例时,页面可能残留上一次操作的状态(比如弹窗未关闭、按钮状态异常、缓存数据未清空):

  • 示例:第一次投标后,页面可能停留在 “支付成功” 提示页,或某些按钮因状态变更无法点击。
  • 影响:后续用例执行时,元素定位会失败(如提示弹窗遮挡按钮),或流程因残留状态报错,导致测试不稳定。

2. clear_deal_page 的核心作用

clear_deal_page 本质是 **“重置页面环境” 的 Fixture**,通常做这些事:

@pytest.fixture()
def clear_deal_page(user_driver):# 1. 跳转到统一的“投标初始化页面”user_driver.get("http://.../deal?reset=1")  # 2. 可能包含清理弹窗、重置按钮状态等操作user_driver.execute_script("window.localStorage.clear();")  # 清理本地缓存return user_driver

  • 重置页面上下文:强制跳转到一个 “干净” 的投标初始页,确保每次用例执行前,页面状态一致(没有残留弹窗、按钮可点击)。
  • 清理缓存 / 状态:通过 JS 清理 localStoragesessionStorage,或关闭残留提示框,避免上一次用例的缓存数据干扰当前用例。

3. 结合 user_driver 的必要性

user_driver 负责维持登录态(共享浏览器实例、保留 Cookie),但无法解决 “页面级的残留状态”:

  • 只靠 user_driver:登录态是保留了,但页面可能因上一次用例操作变得 “不干净”(比如弹窗未关),导致后续用例定位元素超时 / 失败。
  • 结合 clear_deal_page:在保留登录态的基础上,强制重置页面环境,让每个用例都在 “登录且页面干净” 的状态下执行,既复用了登录(提升效率),又避免了页面残留的干扰(保证稳定)。

二、fixture集中管理 

fixture 的使用形式

  • 用例可以直接调用
  • fixture 夹具之间可以进行关联使用
  • fixture 夹具可以完成任意测试用例脚本的前后置编写
  • 一般情况下不同的用例使用自定义的 fixture 进行使用

为了降低用例脚本和 fixture 夹具的耦合性,将 fixture 进行集中管理

fixture 一般统一管理放置项目中固定 conftest.py 文件中

 

fixture 定位顺序:

  • 先从当前运行的 py 文件开始定位 fixture
  • 其次从同级目录的 py 文件中定位 fixture
  • 再从项目包的目录中开始定位定位 fixture
  • 然后从 conftest.py 文件中开始定位 fixture
  • 最后会从项目所有根目录定位 fixture
  • 以上查找定位 fixture 如果没有对应的夹具,那么程序会报错

三、项目重构

对框架代码进行规划和分类

在项目重构的过程中,之前导入的路径使用的模块,会随着目录结构发生变化而变化,不需要手动修改导包路径

  • testcases
    • 封装完成的用例脚本集中管理
  • commons
    • 项目公共模块集中使用包
  • script
    • 用例的线性脚本
  • data
    • 数据文件相关内容
  • log
    • 日志信息相关内容
  • report
    • 缺陷报告记录的内容
  • conftest.py
    • 存放 fixture 夹具的集中管理

 

 

四、统一管理项目驱动

目的:为了方便后期做兼容性测试,使用不同的浏览器来设计驱动获取

from selenium.webdriver import Chrome, Firefox, Ie, Edge, Safari
自定义函数获取对应的浏览器驱动
def get_webdriver(name: str = "chrome"):# 根据调用获取浏览器的实参来返回对应的驱动# 将具体浏览器实参名字进行整理# 将所有浏览器的名字转化为小写# 将所有浏览器的名字中空格去除# 再返回驱动的驱动name = name.lower()name = name.replace(" ", "")# print(name)# 第一种格式:# if name == "chrome":#     return Chrome()# elif name == "firefox":#     return Firefox()# 使用match和case关键字匹配驱动match name:case "chrome":return Chrome()case "firefox":return Firefox()case "ie":return Ie()case "edge":return Edge()

# get_webdriver("C hrome")
# get_webdriver("C H  ro  ME")

自定义获取驱动方式重写之后
  • 需要再创建驱动的地方,调用自定义的get_webdriver ("对应浏览器的名字")

五、后台登录的驱动

# 后台登录页面的驱动
@pytest.fixture(scope="session")
def admin_driver():driver = get_webdriver()driver.get("http://47.107.116.139/fangwei/m.php?m=Public&a=login&")# 使用cookie信息load_cookies(driver)# 如果第一次登录:没有cookie信息那么正常流程登录if is_login(driver):# 验证码处理code = save_code_img(driver)# 完成正常登录流程:使用 POM 封装调用脚本执行page = BackgroundLoginPage(driver)page.login("admin", "msjy123", code)yield driver# 第一次正常登录之后,用例执行结束之后,完成后置保持 cookie 信息save_cookies(driver)

1. 装饰器与 fixture 作用域
@pytest.fixture(scope="session")

  • scope="session":表示该 fixture 的作用域是整个测试会话(session)。也就是说,在一次 pytest 测试运行过程中,这个 admin_driver 夹具只会被初始化一次,然后在所有需要它的测试用例中复用,测试会话结束时才会执行其后置清理逻辑(yield 之后的代码)。这样可以提升测试效率,比如这里用于保持后台登录状态,避免重复登录操作。

 

2. 驱动初始化与页面访问

driver = get_webdriver()
driver.get("http://47.107.116.139/fangwei/m.php?m=Public&a=login&")

  • get_webdriver():调用了一个自定义的函数(这个函数用于根据配置获取对应的浏览器驱动实例,比如 Chrome、Firefox 等浏览器的驱动,方便进行兼容性测试 ),获取到浏览器驱动对象 driver,后续用这个驱动来操作浏览器。
  • driver.get(...):使用获取到的浏览器驱动,打开指定的后台登录页面 URL,让浏览器跳转到对应的登录界面,为后续登录操作做准备。

 

3. Cookie 相关操作

# 使用 cookie 信息
load_cookies(driver)

  • load_cookies(driver):调用自定义函数 load_cookies,作用是尝试从某个地方加载之前保存的 Cookie 信息,并将其注入到当前的浏览器驱动 driver 中。这样做的目的是,如果之前有成功登录过并保存了 Cookie,那么通过加载这些 Cookie,可以直接保持登录状态,无需再次输入账号密码等进行登录,提升测试执行效率。

 

4. 登录流程处理(条件判断)

# 如果第一次登录:没有 cookie 信息那么正常流程登录
if is_login(driver):# 验证码处理code = save_code_img(driver)# 完成正常登录流程:使用 POM 封装调用脚本执行page = BackgroundLoginPage(driver)page.login("admin", "msjy123", code)

  • is_login(driver):调用自定义函数 is_login,用于判断当前浏览器驱动 driver 对应的页面是否处于已登录状态。可能的实现逻辑比如检查页面中是否存在登录后的特定元素(如用户名显示、登录状态标识等 ),或者根据 Cookie 信息判断会话是否有效。如果返回 True,说明需要执行正常的登录流程(一般是首次登录或者 Cookie 失效等情况 )。
  • save_code_img(driver):调用自定义函数 save_code_img,用于处理登录页面的验证码。可能的操作包括截取验证码图片、识别验证码内容(如果结合了验证码识别技术,比如 OCR 等 ),并返回验证码的文本内容 code,以便后续登录时使用。
  • BackgroundLoginPage(driver):这里使用了页面对象模型(POM,Page Object Model )的设计模式,创建一个 BackgroundLoginPage 类的实例 page,并将浏览器驱动 driver 传入。POM 模式把页面的元素定位和操作方法封装到对应的页面类中,便于代码维护和复用。
  • page.login("admin", "msjy123", code):调用 BackgroundLoginPage 类中封装的 login 方法,传入用户名 admin、密码 msjy123 和前面获取到的验证码 code,执行实际的登录操作,模拟用户在页面上输入账号、密码、验证码并提交登录的流程。

 

5. fixture 的 yield 关键字

yield driver

  • yield 是 pytest fixture 中用于分隔前置操作和后置操作的关键字。yield 之前的代码属于前置准备逻辑,执行到 yield 时,会暂停当前 fixture 的执行,将 driver 对象返回给调用它的测试用例使用。当所有依赖该 fixture 的测试用例执行完毕后,会回到这个 fixture,继续执行 yield 之后的代码,也就是后置清理 / 保存操作。

 

6. 后置保存 Cookie 操作

# 第一次正常登录之后,用例执行结束之后,完成后置保持 cookie 信息
save_cookies(driver)

  • save_cookies(driver):调用自定义函数 save_cookies,在测试用例执行完毕后,将当前浏览器驱动 driver 中的 Cookie 信息保存起来(比如保存到文件、数据库等 )。这样,下次再执行测试时,就可以通过前面的 load_cookies 函数加载这些 Cookie,实现免登录或者保持登录状态的效果,提升后续测试的效率,也能模拟实际用户的会话保持场景。

 

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

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

相关文章

Dify工作流:爬虫文章到AI知识库

部署Dify 代码拉取 git clone https://github.com/langgenius/dify.git cd dify/docker启动容器 docker-compose up -d启动成功准备知识库 创建知识库 创建一个空的知识库要先从网址中,找到这个知识库的id,记下后面需要用到。新建API密钥 创建密钥&#…

支付鉴权方案介绍

前后端交互中的鉴权是确保请求来源合法、身份可信、权限合适的关键手段。不同系统架构和业务类型下,使用的鉴权方式略有不同,但主要可分为以下几类: ✅ 一、前后端交互常见的鉴权方式概览 鉴权方式 优点 缺点 适用场景 Cookie + Session 简单、成熟,服务端易控制 不适合跨域…

halcon处理灰度能量图

使用halcon处理射线图像,对高能区域和低能区域分割处理感兴趣区域,筛选区域下的灰度值区间范围。图像灰度值为16位深度图。* 读取灰度图像 read_image (Image, /123.tif)** 获取图像尺寸 get_image_size (Image, Width, Height)* 分割图像为左右两部分&a…

Oracle From查看弹性域设置

打开弹性与设置:【应用开发员->弹性域->说明性->段】打开后界面如下: 把光标定位到标题,然后点击“手电筒”搜索名称(名称就是你要查询的那个弹性域的名称)我这里就是搜索“附加题头信息”&#xff0…

git初始流程

对于一个新项目,从 Git 仓库拉取 test_tool 分支并进行后续修改提交的完整流程如下: 一、首次拉取项目(克隆仓库并切换分支)克隆远程仓库到本地 打开终端(或 PyCharm 的 Terminal),进入你想存放…

emuelec模拟器 ,s905盒子树莓派街机游戏

EmuELEC支持的盒子类型相当广泛,主要包括使用以下芯片方案的机顶盒等设备: S905系列及其变体:如S905、S905D、S905L、S905M、S905X、S905X2、S905X3、S905X4、S905W、S905Y等。 S912:这也是EmuELEC支持的一个常见芯片方案。 S922x…

Ansible部署

Ansible部署 一、部署环境及前置操作 1、测试环境 注:主机复用原测试环境,主机hostname根据需求调整 硬件环境:N100 x86主机 Proxmox系统 软件环境:Ubuntu 22.04.3 LTS 软件版本:redis-7.4.0.tar.gz 主机环境:主机IP …

智慧教室:科技赋能,奏响个性化学习新乐章

在传统教育模式中,课堂互动的局限性犹如一道无形的枷锁,束缚着学生主动学习的热情与能力。课堂上,往往是教师单向的知识输出,仅有少数学生能获得发言机会,大部分学生只能被动聆听,逐渐在枯燥的学习氛围中丧…

Android埋点实现方案深度分析

埋码是数据驱动业务决策、产品优化、用户行为分析的核心基础,其实现方案的优劣直接影响数据的准确性、完整性、实时性、可维护性以及开发效率。 以下从多个维度对主流方案进行剖析: 一、核心目标与挑战目标: 精准采集: 在用户触发…

万界星空科技铜线/漆包线行业智能化MES系统解决方案

万界星空科技针对铜线及漆包线行业开发的智能化MES系统,专门解决该行业原材料管理复杂、工艺控制严、质量追溯困难等核心痛点。该系统通过数字化手段实现生产全流程的可视化与精准控制,助力企业提升生产效率、降低运营成本并增强市场竞争力。一、行业专属…

Git 完全手册:从入门到团队协作实战(3)

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《C修炼之路》、《Linux修炼&#xff1a;终端之内 洞悉真理…

使用Docker搭建SearXNG搜索引擎

1、安装Docker# 安装Docker https://docs.docker.com/get-docker/# 安装Docker Compose https://docs.docker.com/compose/install/# CentOS安装Docker https://mp.weixin.qq.com/s/nHNPbCmdQs3E5x1QBP-ueA2、安装SearXNG详见&#xff1a; https://docs.searxng.org/admin/inst…

基于pi/4-QPSK扩频解扩和gardner环定时同步的通信系统matlab性能仿真

目录 1.引言 2.算法仿真效果演示 3.数据集格式或算法参数简介 4.算法涉及理论知识概要 4.1 π/4-QPSK 4.2 直接序列扩频与解扩 4.3 Gardner环定时同步 5.参考文献 6.完整算法代码文件获得 1.引言 π/4-QPSK是一种特殊的QPSK调制方式&#xff0c;其相邻符号间的相位跳变…

CGA老年人能力评估师:提升老年生活质量

一、CGA老年人能力评估师是提升老年生活质量的“导航者” 老年生活质量的提升&#xff0c;始于对老年人真实需求的精准把握。CGA老年人能力评估师正是这样一群“导航者”&#xff0c;他们运用CGA老年综合评估系统&#xff0c;深入了解老年人在生理、心理、社会参与等方面的状况…

开源的大语言模型(LLM)应用开发平台Dify

概述Dify 是一个开源的大语言模型&#xff08;LLM&#xff09;应用开发平台&#xff0c;结合了后端即服务&#xff08;Backend-as-a-Service&#xff09;和 LLMOps 的理念&#xff0c;旨在帮助开发者快速构建生产级的生成式 AI 应用。它通过直观的界面、强大的功能和灵活的部署…

RAG(检索增强生成)里的文档管理

RAG&#xff08;检索增强生成&#xff09;是结合检索与生成式 AI 的技术框架。核心逻辑是先从外部知识库精准检索相关信息&#xff0c;再将其作为上下文输入大模型生成回答。技术上依赖检索引擎&#xff08;如向量数据库、BM25&#xff09;、大语言模型&#xff08;如 GPT、LLa…

床上肢体康复机器人的机械结构设计cad【7张】三维图+设计说明书

摘要 近年来&#xff0c;随着人口老龄化问题的加重&#xff0c;常年卧床的老年人数增多&#xff0c;同时因为各种疾病的原因&#xff0c;患肢体功能障碍的人数也在增加。严重影响着患者的生活质量&#xff0c;同时给社会和家庭增加了很多麻烦。他们迫切希望尽快康复&#xff0c…

主要分布在背侧海马体(dHPC)CA1区域(dCA1)的时间细胞对NLP中的深层语义分析的积极影响和启示

时间细胞&#xff08;time cells&#xff09;作为海马体CA1区域中编码时间信息的神经元&#xff0c;其工作机制对自然语言处理&#xff08;NLP&#xff09;中的深层语义分析具有多方面的启示。这些神经元通过整合时空信息、动态竞争机制和序列编码能力&#xff0c;为解决NLP中语…

数字ic后端设计从入门到精通12(含fusion compiler, tcl教学)全定制设计进阶

标准单元库中几种时序单元介绍 C2MOS触发器C2MOS触发器的工作分为两个阶段&#xff1a; 1&#xff09;φ0&#xff08;φ1&#xff09;时&#xff0c;第一个三态驱动器导通&#xff08;三态门主要体现在&#xff0c;此时主级处于求值模式。同时从级处在高阻抗模式&#xff0c;即…

Qt调试技巧与常见错误解决方法

一、调试工具与环境配置 1.1 Qt Creator调试器集成 Qt Creator内置GDB/Lldb调试器&#xff0c;支持断点、单步执行、变量监视等功能。 启动调试&#xff1a;按F5或点击"Debug"按钮断点设置&#xff1a;在代码行号旁点击添加断点调试工具栏&#xff1a;包含继续、暂停…