前言

做过 Web UI 自动化测试的小伙伴应该都深有体会 —— 脚本写起来容易,维护起来是真难。页面一改版,元素的 XPath 满天飞;用例一多,重复代码堆积成山;跑完测试只有冷冰冰的控制台日志,出了问题连个截图都没有。

最近针对若依 RuoYi-Vue 后台管理系统搭建了一套企业级的 UI 自动化测试框架,把这些问题都解决了。本文将完整介绍这套框架的设计思路和实现细节,希望能给大家一些参考。

🚀 项目仓库:GitHub | Gitee


一、项目概述

本项目的测试目标系统为若依官方演示站:https://demo.ruoyi.vip/login

框架采用经典的 POM(Page Object Model)三层分层架构,结合 pytest 强大的 fixture 和参数化能力,构建出一套可维护、可复用、可扩展的自动化测试工程。当前已实现的核心测试场景包括:

  • 登录模块自动化测试
  • 用户管理模块的条件查询测试(Excel 数据驱动)

二、技术栈一览

技术 版本 用途
Python 3.12+ 主力编程语言
Selenium 4.0+ Web UI 自动化驱动
pytest 8.0+ 测试用例管理、fixture、参数化
pandas Excel 测试数据读取
Allure 2.0+ 可视化测试报告生成
Ruff 代码质量检查与格式化
Edge WebDriver 浏览器驱动(Microsoft Edge)

三、项目结构 —— POM 三层分层

这是整个框架最核心的部分。目录结构如下:

web_framwork/
├── bases/                     # 【基础封装层】
│   └── base_page.py           # 封装通用浏览器操作
│
├── poms/                      # 【页面对象层】
│   ├── login_page.py          # 登录页 PO
│   └── user_list.py           # 用户列表页 PO
│
├── testcases/                 # 【测试用例层】
│   ├── test_ruoyi.py          # 核心测试用例
│   └── select_user.xlsx       # Excel 测试数据
│
├── commons/                   # 【工具层】
│   └── excel_utils.py         # Excel 数据读取工具
│
├── conftest.py                # pytest 全局 fixture
├── main.py                    # 入口脚本
├── pytest.ini                 # pytest 配置
└── requirements.txt           # 依赖清单

3.1 基础封装层(bases)

文件:bases/base_page.py

这一层对 Selenium 原生 API 进行了二次封装,是整个框架的基石。主要做了以下增强:

  • 统一等待机制:内置了10秒的显式等待,解决页面加载速度不稳定导致的元素定位失败
  • 失败自动截图:定位失败时自动调用 save_screenshot(),保存到 files/ 目录
  • Allure 报告集成:截图通过 allure.attach() 嵌入测试报告
  • iframe 切换封装:若依的页面大量使用 iframe,这里封装了多级菜单点击 + iframe 切换的操作

核心代码骨架:

class BasePage:
    def find_ele(self, loc: str, timeout=10):
        """单元素定位,失败自动截图并上传Allure"""
        try:
            return WebDriverWait(self.driver, timeout).until(
                EC.presence_of_element_located((By.XPATH, loc))
            )
        except TimeoutException:
            # 失败截图并附加到 Allure 报告
            self._take_screenshot_and_attach()
            raise

    def goto_frame(self, menu_xpath: str, frame_src: str):
        """点击侧边栏菜单 + 切换到目标 iframe"""
        self.find_ele(menu_xpath).click()
        self.driver.switch_to.frame(self.find_ele_by_attribute('src', frame_src))

3.2 页面对象层(poms)

文件:poms/login_page.pypoms/user_list.py

按页面维度管理元素定位和页面操作,不包含任何测试断言。以用户列表页为例:

class UserListPage(BasePage):
    # --- 元素定位 ---
    search_login_name = '//input[@placeholder="登录名称"]'
    search_phone      = '//input[@placeholder="手机号码"]'
    select_status     = '//select[@name="status"]'
    btn_search        = '//button[contains(.,"查询")]'

    # --- 页面操作 ---
    def switch_to_user_list(self):
        """通过侧边栏进入用户管理页面"""
        self.goto_frame('//span[text()="用户管理"]', '/system/user')

    def input_login_name(self, name: str):
        if pd.notna(name):
            self.find_ele(self.search_login_name).send_keys(name)

    def select_status_value(self, status):
        if pd.notna(status):
            Select(self.find_ele(self.select_status)).select_by_value(status)

    def click_search(self):
        self.find_ele(self.btn_search).click()

当页面元素变化时,只需修改这一层的 XPath,测试用例完全不受影响。

3.3 测试用例层(testcases)

文件:testcases/test_ruoyi.py

纯粹的测试逻辑,配合 Allure 装饰器构建层级化报告:

@allure.epic("若依后台管理系统")
@allure.feature("用户管理")
class TestRuoyi:

    @allure.story("用户查询")
    @allure.title("条件查询用户 - {loginName}/{phonenumber}/{status}")
    @pytest.mark.parametrize("test_data", load_excel_data("select_user.xlsx", "select_user"))
    @pytest.mark.smoke
    def test_select_user(self, all_case_fixture, test_data):
        """Excel 数据驱动:多种条件组合查询用户"""
        driver = all_case_fixture
        user_page = UserListPage(driver)

        user_page.switch_to_user_list()
        user_page.input_login_name(test_data["loginName"])
        user_page.input_phone(test_data["phonenumber"])
        user_page.select_status_value(test_data["status"])
        user_page.click_search()

        # 验证搜索结果
        result = user_page.get_search_result()
        assert len(result) > 0, "查询结果不能为空"

四、核心特性详解

4.1 登录 Session 复用(Fixture 机制)

文件:conftest.py

每次跑用例都要重新登录是很大的浪费。通过 pytest 的 fixture 机制,在 conftest.py 中定义了全局 fixture:

@pytest.fixture(scope="function")
def all_case_fixture(request):
    driver = webdriver.Edge()
    driver.get("https://demo.ruoyi.vip/login")

    # 手动输入验证码(绕过验证码识别)
    verify_code = input("请输入验证码:")
    LoginPage(driver).login(username="admin", password="admin123", code=verify_code)

    yield driver
    driver.quit()

由于若依的验证码无法自动识别,这里巧妙地采用了控制台交互输入验证码的方式,简单实用。

4.2 Excel 数据驱动

文件:commons/excel_utils.py + testcases/select_user.xlsx

用 Excel 管理测试数据,测试人员无需懂代码也能维护:

loginName phonenumber status
admin 13888888888 0
(空) 13999999999 1
test (空) (空)
def load_excel_data(file_path: str, sheet_name: str) -> list[dict]:
    df = pd.read_excel(file_path, sheet_name=sheet_name, dtype=str)
    return df.to_dict(orient="records")

通过 @pytest.mark.parametrize 将 Excel 数据注入测试用例,一条用例覆盖 N 组数据,大大减少重复代码。

4.3 Allure 可视化测试报告

pytest.ini 中统一配置 Allure 参数:

[pytest]
addopts = -s -v --alluredir=temps --clean-alluredir

运行 python main.py 后自动生成报告:

allure generate temps -o report -c
allure open report

报告中可以看到史诗 → 功能 → 用户故事的层级结构,失败用例附带截图,执行耗时一目了然。

4.4 日志与异常处理

框架全程使用 Python 标准库 logging,关键节点都有日志输出。元素定位失败时不仅截图留证,还会在报告中标记失败原因。


五、快速上手

环境准备

# 1. 克隆项目
git clone https://github.com/S1yexX/Ruoyi-selenium-ui-autotest.git
cd web_framwork

# 2. 创建虚拟环境
python -m venv .venv
.venv\Scripts\activate  # Windows
source .venv/bin/activate  # Mac/Linux

# 3. 安装依赖
pip install -r requirements.txt

# 4. 安装 Allure 命令行工具
# Windows: scoop install allure
# Mac: brew install allure
# Linux: 下载 allure-commandline 并配置 PATH

运行测试

# 运行全部用例
pytest testcases/ -v

# 仅运行冒烟测试
pytest testcases/ -v -m smoke

# 运行并自动生成 Allure 报告
python main.py

⚠️ 注意:运行时控制台会提示输入验证码,请打开浏览器中的若依登录页,查看验证码并输入。


六、项目亮点总结

  1. 标准化 POM 三层架构 —— 元素定位、页面操作、测试逻辑彻底解耦,修改页面不影响用例
  2. 二次封装 Selenium —— 统一等待 + 失败截图 + Allure 集成,告别 flaky 测试
  3. Excel 数据驱动 —— 测试数据与代码分离,非技术人员也能维护
  4. Allure 可视化报告 —— 层级化展示,失败截图嵌入,一目了然
  5. Fixture 会话复用 —— 避免重复登录,提升用例执行效率
  6. 工程化规范 —— pytest.ini + ruff.toml + pyproject.toml 三件套,保证代码质量

七、后续计划

目前框架已实现用户管理模块的查询功能自动化,后续计划扩展:

  • 用户新增 / 编辑 / 删除功能自动化
  • 更多模块覆盖(角色管理、菜单管理、日志管理等)
  • CI/CD 集成(GitHub Actions 自动执行 + Allure 报告发布)
  • 验证码自动识别(OCR 方案)
  • Docker 化运行环境

八、总结

这套框架虽然规模不大,但五脏俱全 —— POM 分层、数据驱动、fixture、Allure 报告、代码规范,每一个点都是企业级自动化测试的标配能力。如果你也在做若依项目的二次开发或者想学习 Selenium + pytest 的实战用法,相信这个项目会对你有所帮助。

欢迎 Star ⭐ 和 PR,一起交流进步!


📌 项目地址

  • GitHub:https://github.com/S1yexX/Ruoyi-selenium-ui-autotest
  • Gitee:https://gitee.com/thousand-rows/ruoyi-selenium-ui-autotest
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐