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:45 阅读更多 →
TPIC7710EVM评估板实战指南:从硬件连接到GUI软件调试

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

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

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

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

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

2026/7/28 21:36:45 阅读更多 →

最新新闻

旅游评论情感分析系统:从爬虫到BERT的全栈实践

旅游评论情感分析系统:从爬虫到BERT的全栈实践

1. 项目概述:旅游评论情感分析系统全栈实现这个项目是我去年指导计算机专业学生完成的毕业设计,一套完整的旅游景点评论分析系统。从数据采集、清洗到情感分析和主题挖掘,覆盖了NLP领域的多个核心技术点。系统采用Python全栈开发,…

2026/7/28 21:43:48 阅读更多 →
模型可解释性:黑盒很酷,但老板要的是安全感

模型可解释性:黑盒很酷,但老板要的是安全感

有一次向高层汇报一个风控模型的进展,我上来就激情洋溢地讲XGBoost的特征重要性排序,SHAP值的蜂群图,还有LIME的局部解释。PPT翻到一半,大老板打断我,问了一句:“你就告诉我,这个模型拒绝一个人…

2026/7/28 21:43:48 阅读更多 →
推荐系统:从协同过滤到深度学习,用户只是想要点新鲜的

推荐系统:从协同过滤到深度学习,用户只是想要点新鲜的

我手机上装过一个新闻App,用了三个月之后,推荐给我的内容就只剩下三样东西:俄乌冲突的最新进展、某科技公司又出了什么新车、以及一位钓鱼博主每天钓了几条鲫鱼。最初是我自己选的,确实点过几次。但当我看了两个月一模一样的新闻框…

2026/7/28 21:43:48 阅读更多 →
想学AI漫剧?看这本书就够!普通人实实在在的副业收入!

想学AI漫剧?看这本书就够!普通人实实在在的副业收入!

想副业赚到钱的朋友们,今天一定要看看漫剧这个赛道。有些人一直在不停换副业,无法长期坚持,核心问题有两个:一个是没利润,大家都在做,高度内卷;二是投入成本高,费时费力,…

2026/7/28 21:43:48 阅读更多 →
异常检测:别老想把离群点干掉,那是情报

异常检测:别老想把离群点干掉,那是情报

刚入行那几年,我对异常点的态度很粗暴:影响模型训练,干掉。箱线图一画,上下须一划拉,须子外面的全删。后来被人问了一句:“你删掉的那些点里,有没有正在偷刷信用卡的骗子?”我突然意…

2026/7/28 21:43:48 阅读更多 →
YOLOv8模型部署全链路优化:从1.2FPS到35FPS的实战指南

YOLOv8模型部署全链路优化:从1.2FPS到35FPS的实战指南

大家好,我是专注于计算机视觉与深度学习部署的开发者。在实际项目中,我们常常遇到这样的困境:一个训练好的 YOLOv8 模型,在推理时帧率(FPS)低得令人沮丧,例如只有 1.2FPS,这完全无法…

2026/7/28 21:42:48 阅读更多 →

日新闻

告别臃肿!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:43 阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

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

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

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

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

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

2026/7/28 0:00:43 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻