Selenium+Pytest自动化测试框架实战
从零搭建 Selenium Pytest 自动化测试框架PO 模式实战作者你的名字发布日期2026-07-28关键词Selenium、Pytest、Page Object、UI 自动化、驱动管理、日志配置 一、写在前面在 UI 自动化测试中代码的可维护性和稳定性是两大核心难题。本文将带你完整实现一个“商品搜索 → 加入购物车 → 断言成功”的自动化用例并贯穿Page ObjectPO设计模式、显式等待、单例驱动管理、日志与 Allure 报告等实用技术。全程基于你实际项目的真实代码所有代码均保留原貌仅增加注释可直接复制运行。 二、项目目录结构项目根目录/ ├── config.py # 全局配置路径、日志、数据读取 ├── utils.py # 工具类驱动管理、元素文本获取 ├── base/ │ └── base_page.py # 需自行补充基础页面父类封装 find_el 等 ├── page/ │ └── buyer_page/ │ ├── index_page.py # 首页页面对象搜索 │ └── goods_page.py # 需自行补充商品详情页页面对象 ├── script/ │ └── buyer_script/ │ └── test_cart.py # 测试用例添加购物车 ├── data/ # 测试数据JSON └── log/ # 日志输出目录⚠️ 注base_page.py和goods_page.py是依赖文件我会在后文给出接口说明你可以根据实际项目实现。 三、基础组件详解核心代码 注释1. 全局配置config.py—— 统一管理项目路径、日志、数据驱动知识点Path(__file__).resolve().parent获取项目根目录避免硬编码。TimedRotatingFileHandler实现日志按天切割便于归档。build_data函数支持从 JSON 文件读取测试数据为数据驱动测试DDT铺路。importosimportjsonimportloggingfromlogging.handlersimportTimedRotatingFileHandlerfrompathlibimportPath# 获取项目根目录的绝对路径无论脚本在哪里执行都能正确定位BASE_PATHPath(__file__).resolve().parentdefbuild_data(file_name): 从 data/ 目录读取指定 JSON 文件返回列表格式的测试数据。 用于 pytest 的 pytest.mark.parametrize 参数化。 filepathos.path.join(BASE_PATH,data,f{file_name}.json)case_data[]try:withopen(filepath,encodingutf-8)asf:all_datajson.load(f)# 加载 JSON 对象字典格式except(FileNotFoundError,json.JSONDecodeError)ase:logging.error(f读取数据文件失败:{filepath}-{e})raise# 将字典的值每个用例的数据提取为列表方便参数化foriinall_data.values():case_data.append(list(i.values()))returncase_datadefbasic_log_config(): 配置日志同时输出到控制台和文件每天午夜切割保留 2 个备份。 避免重复添加 Handler通过判断 logger.handlers 是否为空。 loggerlogging.getLogger()iflogger.handlers:# 已有处理器则跳过防止重复输出returnlogger.setLevel(logging.INFO)# 文件处理器按天切割保留 2 个历史文件lhtTimedRotatingFileHandler(filenameos.path.join(BASE_PATH,log,tp_test.log),whenmidnight,interval1,backupCount2,encodingutf8)# 控制台处理器lslogging.StreamHandler()# 定义日志格式时间 级别 [文件名(函数名:行号)] - 消息formatterlogging.Formatter(fmt%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s)lht.setFormatter(formatter)ls.setFormatter(formatter)logger.addHandler(lht)logger.addHandler(ls)2. 工具类utils.py—— 驱动管理 显式等待封装知识点单例模式通过类变量确保每个端口买家/后台/APP只有一个驱动实例。后台驱动开关设计__admin_key控制是否真正关闭浏览器解决「多用例共用浏览器会话」的痛点避免登录态丢失。get_el_text封装显式等待获取元素文本失败返回None并记录日志便于断言调试。importloggingimportrefromselenium.webdriver.support.waitimportWebDriverWaitfromselenium.webdriver.common.byimportByclassDriverUtils: 驱动管理工具类类变量实现单例 # 三个端口的驱动变量全局唯一__buyer_driverNone__admin_driverNone__app_driverNone# 后台驱动关闭开关默认 False防止误关浏览器__admin_keyFalse# ---------- 买家端 ----------classmethoddefget_buyer_driver(cls):获取买家端驱动若为空则新建 Edge 实例并自动打开首页ifcls.__buyer_driverisNone:fromseleniumimportwebdriver cls.__buyer_driverwebdriver.Edge()cls.__buyer_driver.maximize_window()# 窗口最大化cls.__buyer_driver.implicitly_wait(5)# 隐式等待 5 秒全局超时cls.__buyer_driver.get(http://192.168.1.161/index.php/Home/Index/index)returncls.__buyer_driverclassmethoddefquit_buyer_driver(cls):关闭买家端驱动并释放资源ifcls.__buyer_driverisnotNone:cls.__buyer_driver.quit()cls.__buyer_driverNone# ---------- 后台管理端 ----------classmethoddefget_admin_driver(cls):获取后台驱动仅创建不自动访问任何 URL由测试自行 navigateifcls.__admin_driverisNone:fromseleniumimportwebdriver cls.__admin_driverwebdriver.Edge()cls.__admin_driver.maximize_window()cls.__admin_driver.implicitly_wait(5)returncls.__admin_driverclassmethoddefchange_admin_key(cls,key):外部修改后台驱动关闭开关True 允许关闭False 禁止关闭cls.__admin_keykey logging.info(f后台驱动开关已修改为:{key})classmethoddefquit_admin_driver(cls): 安全关闭后台驱动 - 若开关为 True则真正执行 driver.quit() 关闭浏览器窗口。 - 若开关为 False仅将类变量置为 None不关闭窗口保留会话。 - 无论哪种情况都将变量置空确保下次 get 时重建新驱动。 - 最后将开关重置为 False避免影响其他操作。 ifcls.__admin_driverisnotNone:ifcls.__admin_key:cls.__admin_driver.quit()logging.info(后台浏览器已成功关闭)else:logging.warning(后台驱动开关为 False本次未实际关闭浏览器仅清理对象引用)cls.__admin_driverNonecls.__admin_keyFalse# 使用后复位# ---------- APP端预留 ----------classmethoddefget_app_driver(cls):ifcls.__app_driverisNone:raiseNotImplementedError(APP驱动尚未实现)returncls.__app_driverclassmethoddefquit_app_driver(cls):ifcls.__app_driverisnotNone:cls.__app_driver.quit()cls.__app_driverNone# ---------- 通用页面工具函数 ----------defel_is_exist_by_text(driver,key_text): 通过文本内容判断元素是否存在显式等待最长 10 秒。 若存在返回 WebElement 对象真值若超时返回 False 并截图。 safe_textkey_text.replace(,\\)# 转义双引号防止 XPath 语法错误try:is_sucWebDriverWait(driver,10,1).until(lambdax:x.find_element(By.XPATH,f//*[text(){safe_text}]))exceptExceptionase:is_sucFalse# 将文本中的非法文件名字符替换为下划线防止截图保存失败safe_namere.sub(r[\\/*?:|],_,key_text)driver.get_screenshot_as_file(f{safe_name}_未找到.png)logging.error(f未找到文本为{key_text}的元素对象!)returnis_sucdefget_el_text(driver,xpath_str): 根据 XPath 定位元素并返回其文本内容。 成功返回文本字符串失败返回 None 并记录错误日志。 msgNonetry:msgWebDriverWait(driver,10,1).until(lambdax:x.find_element(By.XPATH,xpath_str)).text logging.info(msg)exceptExceptionase:logging.error(f没有获取到{xpath_str}的元素对象文本!)msgNonereturnmsg3. 首页页面对象page/buyer_page/index_page.py—— 封装搜索业务知识点PO 模式将页面元素定位与业务操作分离提高复用性。继承BuyerBasePage需自行实现使用父类的find_el和input_text方法。定义定位器为元组(By.ID, q)便于统一管理。fromselenium.webdriver.common.byimportByfrombase.base_pageimportBuyerBasePageclassIndexPage(BuyerBasePage): 买家首页页面对象 def__init__(self,driver):self.driverdriversuper().__init__()# 定位器搜索输入框ID 定位self.search_box(By.ID,q)# 定位器搜索按钮XPath 定位匹配 typesubmit 的 buttonself.search_btn(By.XPATH,//button[typesubmit])defquery_goods(self,key_word): 业务方法在首页搜索商品 1. 在搜索框输入关键词 2. 点击搜索按钮 # 调用父类的 input_text 方法先清空再输入self.input_text(self.find_el(self.search_box),key_word)# 找到搜索按钮并点击self.find_el(self.search_btn).click()4. 测试用例script/buyer_script/test_cart.py—— 完整场景 断言知识点使用setup_class/teardown_class管理浏览器生命周期整个类只启动/关闭一次。调用页面对象完成业务操作。断言使用get_el_text获取提示信息并通过assert验证。异常处理中嵌入 Allure 截图方便失败时快速定位问题。# 定义测试类fromconfigimportBASE_PATHfrompage.buyer_page.goods_pageimportGoodsPagefromutilsimportDriverUtils,get_el_textimportallurefromutilsimportDriverUtils,el_is_exist_by_textfrompage.buyer_page.index_pageimportIndexPageimporttimeclassTestGoods:defsetup_class(self):# 打开浏览器获取买家驱动self.driverDriverUtils.get_buyer_driver()# 直接打开搜索页带关键词也可通过首页搜索self.driver.get(http://192.168.1.161/Home/Goods/search.html?qgoods_20260726191738)defteardown_class(self):# 关闭浏览器DriverUtils.quit_buyer_driver()# 定义测试方法deftest_add_cart(self):# 1. 在首页搜索框输入商品关键词并搜索IndexPage(self.driver).query_goods(goods_20260726191738)# 2. 进入商品详情页并点击加入购物车由 GoodsPage 封装GoodsPage(self.driver).add_goods_cart()# 3. 断言判断是否弹出“添加成功”提示try:# 调用 get_el_text 获取提示框文本注意 class 名是 conect-title 而非 content-titlemsgget_el_text(self.driver,//*[classconect-title]/span)assert添加成功inmsgexceptExceptionase:# 若断言失败则截图并附加到 Allure 报告中allure.attach(self.driver.get_screenshot_as_png(),BASE_PATH\img\test_add_cart.png,allure.attachment_type.PNG)raisee time.sleep(2)# 等待页面渲染便于观察结果 四、补充软件测试核心知识扩展阅读1. 为什么用 Page ObjectPO模式提高可维护性页面元素变化只需修改对应 Page 类测试脚本无需改动。增强复用性多个测试用例可共享同一个 Page 类的业务方法如query_goods。清晰分层测试层用例只关心业务逻辑不关心底层 Selenium 操作。2. 显式等待 vs 隐式等待类型作用范围特点隐式等待 (implicitly_wait)全局作用于整个 WebDriver 生命周期设置超时时间轮询查找元素直到找到或超时。显式等待 (WebDriverWait)局部针对特定元素更灵活可设置轮询间隔、忽略异常支持自定义条件。最佳实践混合使用隐式等待作为全局保底显式等待针对关键元素如弹窗、异步加载内容。3. 驱动单例与后台会话保持使用类变量实现单例避免每个测试都创建新浏览器节省资源。后台管理测试中通常需要保持登录状态跨多个用例。通过__admin_key开关控制关闭时机既能清理资源又能复用浏览器窗口极大提升执行效率。4. 日志与 Allure 报告日志记录运行关键信息便于定位环境问题如元素未找到、超时。Allure提供美观的测试报告支持截图、步骤描述、参数展示是团队协作和问题复现的利器。5. 数据驱动测试DDT将测试数据从脚本中分离存放在 JSON / Excel / YAML 文件中。build_data函数读取 JSON 文件配合pytest.mark.parametrize实现一个测试方法跑多组数据极大减少重复代码。 五、运行与调试环境准备Python 3.11安装依赖pip install selenium pytest allure-pytest下载 Edge 浏览器驱动或 Chrome并配置到 PATH。执行命令# 运行单个测试文件pytest script/buyer_script/test_cart.py-v# 生成 Allure 报告需提前安装 allure 命令行pytest script/buyer_script/test_cart.py--alluredirreport allure serve report⚠️ 注意运行前请确保base_page.py和goods_page.py已实现或根据你的项目调整导入并创建log/和data/目录若未创建日志写入会报错。 六、常见踩坑与解决方案来自真实调试记录现象原因解决方案assert 添加成功 in msg报 TypeErrormsg 为 NoneXPath 写错实际 class 名为conect-title而非content-title使用浏览器 F12 → 右键元素 → Copy XPath杜绝手写错误BASE_PATH \img\test_add_cart.png报类型错误BASE_PATH是Path对象不能直接加字符串使用os.path.join(BASE_PATH, img, test_add_cart.png)或str(BASE_PATH)多个用例执行时第二个用例报InvalidSessionIdException上一个用例关闭了浏览器驱动会话失效使用DriverUtils的后台开关保持浏览器常驻✅ 七、总结本文从零开始构建了一个企业级 UI 自动化框架的雏形核心亮点包括清晰的目录分层与 PO 封装健壮的驱动管理支持多端 后台会话保持日志与 Allure 报告集成数据驱动预留接口所有代码均来自真实项目可直接运行。希望这份笔记能帮助你快速上手自动化测试提升测试效率与代码质量。 如果你需要完整的base_page.py和goods_page.py实现欢迎在评论区留言我会尽快补充。如果觉得有用请点赞、收藏、分享让更多测试小伙伴受益

相关新闻

GEOS-5 FP-IT 同化与 OMI/Aura UV-2 1 轨道 L2 支持 Swath 13x24km V3 (OMUFPITMET)

GEOS-5 FP-IT 同化与 OMI/Aura UV-2 1 轨道 L2 支持 Swath 13x24km V3 (OMUFPITMET)

GEOS-5 FP-IT Assimilation Geo-colocated to OMI/Aura UV-2 1-Orbit L2 Support Swath 13x24km V3 (OMUFPITMET) 简介 与 OMI/Aura UV-2 1 轨道 L2 支持条带 13x24km 同化的 GEOS-5 FP-IT 同化地理共定位 (OMUFPITMET) 提供来自 GEOS-5 仪器团队前向处理 (FP-IT) 同化产品的…

2026/7/28 21:36:59阅读更多 →
TPIC7710EVM评估板实战指南:从硬件连接到GUI软件调试

TPIC7710EVM评估板实战指南:从硬件连接到GUI软件调试

1. 评估板的核心价值与TPIC7710EVM概述在嵌入式硬件开发,尤其是涉及电机驱动、电源管理这类对实时性和可靠性要求极高的领域,直接上手一颗全新的芯片进行系统设计,无异于“盲人摸象”。数据手册上的参数是静态的,而实际应用中的动…

2026/7/28 21:36:59阅读更多 →
Linux桌面生态构建指南:从工具链思维到生产力环境搭建

Linux桌面生态构建指南:从工具链思维到生产力环境搭建

很多人对 Linux 的认知,还停留在“命令行黑屏”、“开发专用”、“软件难找”的阶段。几年前,当我第一次尝试将主力工作环境切换到 Linux 时,也经历过类似的困惑:写文档用什么?处理图片用什么?日常沟通又用…

2026/7/28 21:36:59阅读更多 →
Jakarta EE 实验 — Web 聊天室(JSP版)

Jakarta EE 实验 — Web 聊天室(JSP版)

Jakarta EE 实验 — Web 聊天室(JSP版) 摘要:本文将基于 IntelliJ IDEA 2025.2.2、Jakarta EE 架构(使用 Jakarta Servlet API)、JDK 21 和 Tomcat 10+ 服务器,提供详细的实验步骤、完整的代码、详细的代码解释以及测试过程。整个实现严格遵循实验要求:基于 Ser…

2026/7/28 22:47:21阅读更多 →
汽车电子ASIC评估实战:TPIC7710 EVM硬件解析与GUI软件深度操作指南

汽车电子ASIC评估实战:TPIC7710 EVM硬件解析与GUI软件深度操作指南

1. 项目概述:从芯片到系统的评估桥梁在汽车电子,特别是车身控制与底盘电子领域,专用集成电路(ASIC)扮演着核心角色。它们将复杂的逻辑控制、驱动保护、通信接口等功能集成于单一芯片,旨在实现高可靠性、高集…

2026/7/28 22:47:21阅读更多 →
Quickemu深度实战:三步骤高效创建多平台虚拟机环境

Quickemu深度实战:三步骤高效创建多平台虚拟机环境

Quickemu深度实战:三步骤高效创建多平台虚拟机环境 【免费下载链接】quickemu Quickly create and run optimised Windows, macOS and Linux virtual machines 项目地址: https://gitcode.com/GitHub_Trending/qu/quickemu 在当今多系统开发与测试需求日益增…

2026/7/28 22:47:21阅读更多 →
生产环境中的gin pprof middleware:安全访问控制与性能数据采集最佳实践

生产环境中的gin pprof middleware:安全访问控制与性能数据采集最佳实践

生产环境中的gin pprof middleware:安全访问控制与性能数据采集最佳实践 【免费下载链接】pprof gin pprof middleware 项目地址: https://gitcode.com/gh_mirrors/ppr/pprof gin pprof middleware是一款专为Gin框架设计的性能分析中间件,能够帮助…

2026/7/28 22:47:21阅读更多 →
Python多线程环境下连接对象的线程安全实践

Python多线程环境下连接对象的线程安全实践

1. 为什么需要关注连接对象的线程安全? 在Python多线程环境中处理连接对象时,最容易被忽视却最致命的问题就是线程安全。我曾在实际项目中遇到过这样的场景:一个看似运行良好的多线程数据库应用,在线上环境运行几天后突然开始出现…

2026/7/28 22:47:21阅读更多 →
11,000+安全漏洞检测模板:Nuclei Templates终极实战指南

11,000+安全漏洞检测模板:Nuclei Templates终极实战指南

11,000安全漏洞检测模板:Nuclei Templates终极实战指南 【免费下载链接】nuclei-templates Community curated list of templates for the nuclei engine to find security vulnerabilities. 项目地址: https://gitcode.com/GitHub_Trending/nu/nuclei-templates …

2026/7/28 22:45:21阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/28 4:06:39阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/28 2:08:06阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/28 1:38:28阅读更多 →
告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:29阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:29阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:29阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/28 20:22:24阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/28 3:17:03阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →