详细介绍:【Selenium】UI自动化测试框架设计:从项目结构到Base-Page层的最佳实践

news/2025/9/24 20:10:10/文章来源:https://www.cnblogs.com/yfceshi/p/19109879

UI自动化测试框架设计:从项目结构到Base-Page层的最佳实践

全面解析UI自动化测试项目的架构设计与实现细节,构建可维护的测试框架

在现代软件开发中,UI自动化测试已成为确保产品质量的重要环节。一个良好的项目结构和合理的设计模式能够显著提高测试代码的可维护性和扩展性。本文将深入探讨UI自动化测试项目的整体结构设计以及Base层与Page层的详细实现。


️ 整体项目结构设计

项目结构全景视图

UI自动化测试项目
核心代码层
测试用例层
资源文件层
输出报告层
脚本工具层
文档层
页面对象模块
业务动作模块
通用组件模块
工具类模块
按业务域组织
测试固件
环境配置
测试数据
图像资源
HTML报告
Allure报告
执行日志
运行脚本
CI/CD配置
设计文档
编码规范

完整项目目录结构

ui-automation-project/
├── README.md                      # 项目说明文档
├── requirements.txt               # Python依赖列表
├── .gitignore                    # Git忽略配置
├── src/                          # 核心源代码
│   ├── pages/                    # 页面对象层
│   │   ├── base_page.py          # 页面基类
│   │   ├── login_page.py         # 登录页面
│   │   └── home_page.py          # 首页页面
│   ├── actions/                  # 业务动作层
│   │   └── login_actions.py      # 登录业务流程
│   ├── components/               # 通用组件
│   │   └── header.py             # 页面头部组件
│   └── utils/                    # 工具类
│       ├── driver_factory.py     # 驱动工厂
│       ├── config.py             # 配置管理
│       ├── logger.py             # 日志工具
│       └── wait_utils.py         # 等待工具
├── tests/                        # 测试用例
│   ├── conftest.py              # pytest配置
│   ├── login/                   # 登录模块测试
│   └── order/                   # 订单模块测试
├── resources/                   # 资源文件
│   ├── config/                  # 配置文件
│   │   ├── dev.yaml             # 开发环境
│   │   └── prod.yaml            # 生产环境
│   ├── testdata/                # 测试数据
│   └── images/                  # 图片资源
├── reports/                     # 测试报告
│   ├── html/                   # HTML报告
│   ├── allure_raw/             # Allure原始数据
│   └── logs/                   # 运行日志
└── scripts/                    # 脚本工具
├── run.py                  # 运行脚本
└── docker_run.sh           # Docker脚本

各层级的职责与内容

项目各模块职责划分

模块职责说明示例文件变化频率
pages/封装页面元素和操作login_page.py
actions/封装业务流程login_actions.py
components/封装可复用UI组件header.py
utils/提供工具函数driver_factory.py
tests/存放测试用例test_login.py
resources/存储测试资源dev.yaml, testdata/
reports/输出测试结果html/, logs/

Base层与Page层的详细设计

Base层与Page层的关系

Base层与Page层职责对比

特性Base层(BasePage)Page层(具体页面类)
职责提供通用页面操作方法封装具体页面元素和业务操作
内容框架级别的通用功能页面特定的元素定位和操作
变化频率低(相对稳定)中(随页面变化而调整)
继承关系通常继承自object继承自BasePage
复用性高(所有页面共享)中(特定页面使用)

BasePage基类核心实现

class BasePage
:
"""所有页面对象的基类,封装通用页面操作"""
def __init__(self, driver):
self.driver = driver
self.timeout = 30
# 元素操作相关方法
def find_element(self, locator, timeout=None):
"""查找单个元素(显式等待)"""
timeout = timeout or self.timeout
return WebDriverWait(self.driver, timeout).until(
EC.presence_of_element_located(locator)
)
def click(self, locator, timeout=None):
"""点击元素"""
element = self.find_element(locator, timeout)
element.click()
def input_text(self, locator, text, timeout=None):
"""输入文本"""
element = self.find_element(locator, timeout)
element.clear()
element.send_keys(text)
# 页面导航相关方法
def get_current_url(self):
"""获取当前页面URL"""
return self.driver.current_url
def refresh_page(self):
"""刷新页面"""
self.driver.refresh()
# 更多通用方法...

具体页面类实现示例

class LoginPage
(BasePage):
"""登录页面对象"""
# 元素定位器
USERNAME_INPUT = (By.ID, "username")
PASSWORD_INPUT = (By.ID, "password")
LOGIN_BUTTON = (By.ID, "loginBtn")
ERROR_MESSAGE = (By.CLASS_NAME, "error-message")
def __init__(self, driver):
super().__init__(driver)
self.url = "https://example.com/login"
def open(self):
"""打开登录页面"""
self.driver.get(self.url)
return self
def enter_username(self, username):
"""输入用户名"""
self.input_text(self.USERNAME_INPUT, username)
return self
def enter_password(self, password):
"""输入密码"""
self.input_text(self.PASSWORD_INPUT, password)
return self
def click_login(self):
"""点击登录按钮"""
self.click(self.LOGIN_BUTTON)
from .home_page import HomePage # 避免循环导入
return HomePage(self.driver)
def login_with_credentials(self, username, password):
"""使用凭据登录(业务流程封装)"""
return (self.open()
.enter_username(username)
.enter_password(password)
.click_login())

项目结构演进策略

阶段一:最小可行产品(第1-3天)

目标:快速跑通主业务流程

project/
└── tests/
└── checkout_flow/       # 主业务流程
├── __init__.py
├── fixtures.py      # 专用测试固件
└── test_checkout.py # 核心测试用例

特点

  • 直接在使用例中编写自动化代码
  • 不需要抽象分层
  • 快速验证业务流程

阶段二:模块化扩展(第1周)

目标:支持多个业务模块

project/
└── tests/
├── checkout_flow/       # 现有流程
├── order/              # 新订单模块
│   ├── __init__.py
│   ├── fixtures.py
│   ├── test_order_list.py
│   └── test_cancel_order.py
└── payment/            # 支付模块
├── __init__.py
├── fixtures.py
├── test_pay_success.py
└── test_pay_fail.py

阶段三:代码抽象与复用(第3周)

目标:消除重复代码,提高复用性

project/
└── tests/
├── checkout_flow/
├── order/
│   ├── pages/          # 模块专用页面对象
│   │   ├── order_list_page.py
│   │   └── order_detail_page.py
│   ├── actions/        # 模块专用业务动作
│   │   └── cancel_action.py
│   ├── fixtures.py
│   └── test_*.py
├── payment/
│   ├── pages/
│   │   └── payment_page.py
│   ├── actions/
│   │   └── pay_action.py
│   ├── fixtures.py
│   └── test_*.py
└── shared/             # 跨模块共享代码
├── driver.py
└── config.py

最佳实践总结

1. 分层设计原则

层级职责变化频率设计原则
测试用例业务验证保持简洁,只包含断言和业务调用
页面对象元素封装封装页面细节,提供业务方法
工具类基础能力提供稳定可靠的底层支持

2. 代码组织策略

在这里插入图片描述

3. 设计模式应用

页面工厂模式
class PageFactory
:
"""页面工厂,统一管理页面对象创建"""
def __init__(self, driver):
self.driver = driver
self._pages = {
}
def get_page(self, page_class):
"""获取页面实例(单例模式)"""
if page_class not in self._pages:
self._pages[page_class] = page_class(self.driver)
return self._pages[page_class]
组件化设计
class BaseComponent
(BasePage):
"""基础组件类"""
def __init__(self, driver, container_locator):
super().__init__(driver)
self.container = container_locator
def find_in_container(self, locator):
"""在容器内查找元素"""
container = self.find_element(self.container)
return container.find_element(*locator)

✅ 总结

构建优秀的UI自动化测试项目需要综合考虑项目结构和代码设计:

  1. 合理的项目结构是维护性的基础,应该按业务域组织代码而不是技术类型
  2. Base-Page模式是UI自动化的核心,通过合理的职责划分提高代码复用性
  3. 渐进式演进允许项目随着需求增长而自然优化,避免过度设计
  4. 设计模式应用如工厂模式和组件化设计能够进一步提高代码质量

通过本文介绍的项目结构设计和Base-Page层实现方案,你可以构建出健壮、可维护、可扩展的UI自动化测试框架,显著提高测试代码的质量和开发效率。

记住:最好的项目结构不是一开始就设计出来的,而是在项目演进过程中不断优化形成的。始终保持代码的简洁性和可维护性,让自动化测试成为软件开发的有力支撑而不是负担。

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

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

相关文章

P13754 【MX-X17-T3】Distraction

原题链接:P13754 【MX-X17-T3】Distraction - 洛谷 非常好的题,非常好的思想。简单思想的结合体就是不易察觉的难题。这题实际上就两个难点:1. 处理每个点的权值 \(v_i\)。2. 推导交换权值并找出最长字段和 首先对于…

台州自助建站系统热门国际新闻

从Manus到OpenManus:AI智能体技术如何重塑未来生活场景? 一、现状:AI智能体技术面临的三大核心矛盾 (通过分析用户高频痛点与市场反馈提炼) 能力与门槛的失衡 Manus展示的复杂任务处理能力(如股票分析、代…

2025.9.24

今天上早八离散数学,认真听课发现真听懂了,然后是马克思主义基本原理,老师话很亲切,中午吃饭没休息,又出发修改表格格式了,弄了3个小时,外卖被偷了,我又点了一份,然后洗澡,没带洗发水用香皂洗头,效果不好,…

初学汇编

寄存器 存储数据速度:cpu > 内存 > 硬盘通用寄存器 寄存器是在cpu中的8位 16位 32位EAX AX ALEBX BX BLECX CX CLEDX DX DLESP SP AHEBP BP CHESI SI DHEDI DI BH内存地址的五种形式 1.立即数:如0x13FFC4 2.[r…

架构图设计还得是华为 - 智慧园区

在数字化时代,架构图就像建筑工程的设计蓝图,是技术系统从抽象想法落地为实际产品的关键桥梁。无论是手机芯片的内部逻辑布局,还是全球通信网络的节点连接,清晰、科学的架构图都能让复杂的技术体系变得“可视化”,…

解决zsh: corrupt history file /home/sgud4h5gh/.zsh_history的办法

问题 在一次重装Ubuntu随后进行了一些修改的情况下,输入命令会出现报错zsh: corrupt history file /home/sgud4h5gh/.zsh_history 并且好像不能执行,实际上是因为文件.zsh_history出现损坏或者乱码的情况。 首先要知…

StarRocks GitHub 工作流程

StarRocks项目遵循GitHub工作流规范,其中包含若干实用建议(例如保持本地环境与上游仓库同步并及时提交)。本文档详细说明在GitHub平台完成StarRocks开发的完整工作流程。 第一步:云端分叉项目访问:https://github…

【Selenium】消除Selenium报错:ChromeDriver与Chrome浏览器版本不匹配

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

伍佰亿搜索引擎网站系统企业科技网站建设

如何在apache Arrow定位与解决问题 最近在执行sql时做了一些batch变更,出现了一个 crash问题,底层使用了apache arrow来实现。本节将会从0开始讲解如何调试STL源码crash问题,在这篇文章中以实际工作中resize导致crash为例,引出如何…

2013网站建设方案沃尔玛商城

本人使用谷歌搜索了简中互联网,完全没有找到任何有关 ANAME 的文章……本文该不会是头一份吧 相信大家对于 DNS 的解析方式都不陌生,常见的有 A、CNAME、MX、TXT 记录等等。其中,网站常用的是 A 记录和 CNAME 记录:A 记录用于将域…

对象初始化器的使用方法

1. 什么是对象初始化器? 对象初始化器就是一种在创建对象的同时,直接给属性赋值的写法。不用先 new 一个对象,再一行一行地赋值。 它的作用是用来给对象初始化的 一定存在:必然要执行构造方法 2. 构造方法与对象初…

C++、Java 和 Python 在输入输出差别

C++、Java 和 Python 在输入输出(I/O)格式上有显著差异,主要体现在语法风格、处理方式和灵活性上。以下从标准输入输出、文件操作两个维度对比三者的差异,并结合示例说明核心特点。 一、标准输入输出(控制台 I/O)…

我的学习记录之自我介绍、思维导图和监督措施

一、关于我: 目前就读于中南林业科技大学涉外学院数据科学与大数据技术专业大三,介绍一下自己,在我之前的学习生活中我一般是班级里小透明的存在,成绩一直处于中等偏上,但是又不调皮捣蛋,所以老师一般不会有特别…

用 Java 和 Tesseract 进行验证码识别:基础实现与优化

验证码(CAPTCHA)是防止自动化攻击的常见手段。然而,在某些场景下,如自动化测试或者爬虫平台,可能需要识别和处理验证码图像。本文将指导你如何使用 Java 和 Tesseract OCR(光学字符识别)库来实现验证码识别,并…

新网站应该怎么做料神wordpress建站教程

A12435 思路:只有4中情况:A1,A2翻转,其他正常,A2A3翻转其他正常.....为了下标与数字对应我开了6个空间,然后从1开始循环,到4截止,因为循环中有i1害怕数组越界,如果索引出的数与下标不相等了&…

教育类网站开发文档上海工程项目查询

仓库建设 luogu 2120 题目大意 有一个斜坡,上面有n个工厂(山顶是1,山脚是nnn,工厂都是漏填),上面有pip_ipi​个货物,和工厂1的距离为x1x_1x1​ 现在有一场大雨,你可以在某些工厂处…

网站开发项目工期流程手机版网页

BERT:深度学习领域中的语言理解利器 摘要 BERT(双向编码器表示法自转换器)是一种领先的深度学习模型,它在许多语言理解任务中都显示出卓越的性能。BERT模型基于转换器编码器架构,并通过自监督学习在大量未标记文本数…

Java第二次实验

1. 本章学习总结 本章学习了Java多方面知识:控制台输入推荐用Scanner.nextLine()避免问题,还涉及 IDE 操作与 String.split;身份证排序用Arrays.sort和String.subString,结构化编程且注意输入方法;需了解 StringB…

详细介绍:【2025PolarCTF秋季个人赛】WEB方向wp

详细介绍:【2025PolarCTF秋季个人赛】WEB方向wppre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", …

英语_阅读

当然可以,以下是英文与中文交替的逐句翻译:Six-year-old Brooke Neitzel wanted a dollhouse. 六岁的布鲁克奈策尔想要一个娃娃屋。 So she ordered one just by telling the familys smart speaker what she wanted…