# UI_AutoTest **Repository Path**: lr_1_0/UI_AutoTest ## Basic Information - **Project Name**: UI_AutoTest - **Description**: 这是一个基于 Python + Playwright + Pytest 的现代化 UI 自动化测试框架,采用 Page Object Model (POM) 设计模式 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2026-02-20 - **Last Updated**: 2026-02-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 🎯 UI 自动化测试框架 - 完整使用指南 ## 📋 目录 - [框架概述](#框架概述) - [项目结构](#项目结构) - [核心文件说明](#核心文件说明) - [快速开始](#快速开始) - [编写测试用例](#编写测试用例) - [配置说明](#配置说明) - [最佳实践](#最佳实践) - [常见问题](#常见问题) --- ## 🎯 框架概述 这是一个基于 **Python + Playwright + Pytest** 的现代化 UI 自动化测试框架,采用 **Page Object Model (POM)** 设计模式,具有以下特点: - ✅ **Page Object Model** - 页面对象模式,代码复用性高 - ✅ **数据驱动** - 支持 JSON/YAML 数据文件 - ✅ **多浏览器支持** - Chromium、Firefox、WebKit - ✅ **自动报告** - HTML 报告、Allure 报告 - ✅ **视频录制** - 自动录制测试视频(仅保留失败测试) - ✅ **截图功能** - 测试失败自动截图 - ✅ **日志系统** - 完整的日志记录 - ✅ **并行执行** - 支持 pytest-xdist 并行运行 - ✅ **Playwright MCP** - AI 助手集成,支持智能浏览器自动化 --- ## 📁 项目结构 ``` ui_frame/ │ ├── 📂 pages/ # 页面对象层(Page Object Model) │ ├── __init__.py # 包初始化文件 │ ├── base_page.py # 基础页面类(所有页面继承此类) │ ├── login_page.py # 登录页面对象(示例) │ └── my_login_page.py # 自定义登录页面对象 │ ├── 📂 tests/ # 测试用例层 │ ├── __init__.py # 包初始化文件 │ ├── test_demo.py # 演示测试用例 │ ├── test_login.py # 登录测试用例(示例) │ └── test_my_login.py # 自定义登录测试用例 │ ├── 📂 utils/ # 工具类层 │ ├── __init__.py # 包初始化文件 │ ├── logger.py # 日志工具类 │ ├── config_reader.py # 配置文件读取工具 │ ├── page_utils.py # 页面操作工具类 │ └── data_manager.py # 测试数据管理工具 │ ├── 📂 config/ # 配置文件目录 │ └── test_config.yaml # 测试配置文件(环境、URL、浏览器等) │ ├── 📂 test_data/ # 测试数据目录 │ └── login_data.json # 登录测试数据 │ ├── 📂 reports/ # 测试报告目录(自动生成) │ ├── screenshots/ # 失败截图 │ ├── videos/ # 测试视频(仅失败测试) │ ├── report.html # HTML 测试报告 │ └── allure-results/ # Allure 报告数据 │ ├── 📂 logs/ # 日志文件目录(自动生成) │ └── test_YYYYMMDD.log # 按日期生成的日志文件 │ ├── 📄 conftest.py # Pytest 全局配置文件(核心) ├── 📄 pytest.ini # Pytest 配置文件 ├── 📄 playwright.config.py # Playwright 配置(当前未使用) ├── 📄 requirements.txt # Python 依赖包列表 ├── 📄 .env.example # 环境变量示例文件 ├── 📄 .gitignore # Git 忽略文件配置 ├── 📄 run_tests.py # 自定义测试运行脚本 ├── 📄 setup.py # 完整安装脚本 ├── 📄 quick_setup.py # 快速安装脚本 ├── 📄 README.md # 项目说明文档 └── 📄 框架使用指南.md # 本文件 ``` --- ## 📚 核心文件说明 ### 1. `conftest.py` - Pytest 全局配置(⭐ 核心文件) **作用**:Pytest 的全局配置文件,自动被所有测试识别和使用。 **主要功能**: - 🔧 **浏览器启动配置** - 设置 headless 模式、启动参数 - 🔧 **浏览器上下文配置** - 设置窗口大小、视频录制 - 🔧 **页面 Fixture** - 为每个测试提供 `page` 对象 - 🔧 **超时设置** - 全局默认超时 20 秒,导航超时 30 秒 - 🔧 **测试信息记录** - 自动记录测试名称、结果 - 🔧 **视频管理** - 自动删除成功测试的视频,保留失败测试的视频 - 🔧 **截图功能** - 测试失败时自动截图 - 🔧 **环境初始化** - 自动创建必要的目录 **关键配置**: ```python # 浏览器启动参数 headless: True # 后台运行,不显示浏览器窗口 slow_mo: 100 # 每个操作延迟 100ms(便于调试) # 超时设置 page.set_default_timeout(20000) # 元素操作默认 20 秒 page.set_default_navigation_timeout(30000) # 页面导航默认 30 秒 # 视频录制 record_video_dir: "reports/videos/" # 视频保存目录 # 自动删除成功测试的视频,保留失败测试的视频 ``` --- ### 2. `pytest.ini` - Pytest 配置文件 **作用**:配置 Pytest 的运行参数和标记。 **主要配置**: ```ini [tool:pytest] testpaths = tests # 测试文件搜索路径 addopts = --html=reports/report.html # 生成 HTML 报告 --alluredir=reports/allure-results # Allure 报告目录 --video retain-on-failure # 只保留失败测试的视频 --screenshot only-on-failure # 只在失败时截图 -v # 详细输出 --tb=short # 简短的错误追踪 markers = # 自定义标记 smoke: 冒烟测试 regression: 回归测试 ui: UI界面测试 ``` --- ### 3. `config/test_config.yaml` - 测试配置文件 **作用**:集中管理测试环境、URL、浏览器等配置。 **主要配置项**: ```yaml test: base_url: "http://147.108.157.133:8090" # 测试环境 URL environment: "test" # 环境名称 retry_count: 2 # 重试次数 implicit_wait: 10 # 隐式等待时间 browser: headless: true # 无头模式 slow_mo: 100 # 操作延迟 timeout: 30000 # 浏览器超时 viewport: width: 1920 height: 1080 test_data: users: zhangsan: username: "zhangsan" password: "123456" ``` --- ### 4. `pages/base_page.py` - 基础页面类 **作用**:所有页面对象的基类,提供通用的页面操作方法。 **主要方法**: - `navigate()` - 导航到页面(抽象方法,子类需实现) - `is_loaded()` - 检查页面是否加载完成(抽象方法,子类需实现) - `wait_for_page_load()` - 等待页面加载完成 - `click_element()` - 点击元素 - `fill_text()` - 填写文本 - `get_element_text()` - 获取元素文本 - `is_element_visible()` - 检查元素是否可见 - `take_screenshot()` - 截图 **使用示例**: ```python from pages.base_page import BasePage class MyPage(BasePage): def navigate(self): self.page.goto(self.page_url) def is_loaded(self): return self.is_element_visible("#main-content") ``` --- ### 5. `utils/page_utils.py` - 页面操作工具类 **作用**:提供底层的页面操作工具方法。 **主要方法**: - `wait_for_element()` - 等待元素出现(默认 30 秒) - `safe_click()` - 安全点击(带异常处理) - `safe_fill()` - 安全填写(带异常处理) - `get_text()` - 获取元素文本 - `is_element_visible()` - 检查元素可见性(默认 10 秒) - `wait_for_page_load()` - 等待页面加载(networkidle) - `scroll_to_element()` - 滚动到元素 - `take_screenshot()` - 截图 - `execute_script()` - 执行 JavaScript **等待策略**: - `wait_for_element`: 30 秒超时,等待元素可见 - `is_element_visible`: 10 秒超时,不抛异常 - `wait_for_page_load`: 30 秒超时,等待 networkidle --- ### 6. `utils/logger.py` - 日志工具 **作用**:提供统一的日志记录功能。 **特点**: - 自动按日期生成日志文件 - 日志保存到 `logs/` 目录 - 支持不同日志级别(DEBUG、INFO、WARNING、ERROR) **使用示例**: ```python from utils.logger import get_logger logger = get_logger(__name__) logger.info("开始执行测试") logger.error("测试失败") ``` --- ### 7. `utils/config_reader.py` - 配置读取工具 **作用**:读取 YAML 配置文件。 **使用示例**: ```python from utils.config_reader import ConfigReader config = ConfigReader() base_url = config.get("test.base_url") ``` --- ### 8. `utils/data_manager.py` - 数据管理工具 **作用**:管理测试数据(JSON 文件)。 **使用示例**: ```python from utils.data_manager import DataManager data = DataManager.get_test_data("login_data.json", "login_test") username = data["username"] ``` --- ### 9. `pages/my_login_page.py` - 自定义页面对象示例 **作用**:展示如何创建自定义页面对象。 **关键特性**: - 继承 `BasePage` - 定义页面元素选择器 - 实现业务方法(如 `login()`、`login_with_alert_check()`) - 处理特殊场景(如 Alert 弹框) **Alert 处理示例**: ```python def login_with_alert_check(self, username: str, password: str): """登录并捕获 Alert 弹框""" def handle_dialog(dialog): alert_message = dialog.message dialog.accept() self.page.on("dialog", handle_dialog) # ... 登录操作 ``` --- ### 10. `tests/test_my_login.py` - 测试用例示例 **作用**:展示如何编写测试用例。 **关键特性**: - 使用 `@pytest.mark` 标记测试 - 使用 `page` fixture(自动注入) - 使用页面对象进行操作 - 使用断言验证结果 **示例**: ```python class TestLogin: @pytest.fixture(autouse=True) def setup(self, page: Page): self.page = page self.login_page = MyLoginPage(page) @pytest.mark.smoke @pytest.mark.ui def test_valid_login(self): self.login_page.navigate() success = self.login_page.login("zhangsan", "123456") assert success, "登录应该成功" ``` --- ## 🚀 快速开始 ### 1. 环境准备 #### 安装 Python 依赖 ```bash # 安装 Python 包 pip install -r requirements.txt # 安装 Playwright 浏览器 playwright install chromium ``` #### 配置 Playwright MCP(可选,用于 AI 助手) Playwright MCP 允许 AI 助手(如 Cursor)通过结构化命令控制浏览器,提供更智能的测试生成和自动化能力。 **快速配置(推荐)**: ```powershell # Windows PowerShell .\setup_playwright_mcp.ps1 ``` **手动配置**: 1. 确保已安装 Node.js 18+ (`node --version`) 2. 编辑 Cursor 设置文件:`%APPDATA%\Cursor\User\settings.json` 3. 添加以下配置: ```json { "mcpServers": { "playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] } } } ``` 4. 重启 Cursor 详细配置说明请参考:[PLAYWRIGHT_MCP_SETUP.md](./PLAYWRIGHT_MCP_SETUP.md) #### 配置环境变量(可选) ```bash # 复制示例文件 cp .env.example .env # 编辑 .env 文件 BASE_URL=http://147.108.157.133:8090 TEST_ENV=test ``` --- ### 2. 修改配置 #### 修改测试 URL 编辑 `config/test_config.yaml`: ```yaml test: base_url: "http://你的网站地址:端口" ``` #### 修改浏览器设置 编辑 `conftest.py`: ```python # 第 12 行:headless 模式 "headless": True # True = 后台运行,False = 显示浏览器窗口 ``` --- ### 3. 运行测试 #### 运行所有测试 ```bash # 方式 1:使用 pytest pytest tests/ -v # 方式 2:使用自定义脚本 python run_tests.py ``` #### 运行指定测试 ```bash # 运行单个测试文件 pytest tests/test_my_login.py -v # 运行单个测试用例 pytest tests/test_my_login.py::TestLogin::test_valid_login -v # 运行标记的测试 pytest -m smoke -v # 运行所有 smoke 标记的测试 ``` #### 查看报告 ```bash # HTML 报告 # 自动生成在 reports/report.html # 用浏览器打开即可查看 # Allure 报告 allure serve reports/allure-results ``` --- ## ✍️ 编写测试用例 ### 步骤 1:创建页面对象 在 `pages/` 目录下创建新的页面对象文件,例如 `pages/home_page.py`: ```python from pages.base_page import BasePage from utils.logger import get_logger logger = get_logger(__name__) class HomePage(BasePage): """首页页面对象""" # 定义页面元素选择器 SEARCH_INPUT = "#search-input" SEARCH_BUTTON = "#search-button" page_loaded_indicator = SEARCH_INPUT def __init__(self, page): super().__init__(page) self.page_url = f"{self.base_url}/home" def navigate(self): """导航到首页""" logger.info(f"导航到首页: {self.page_url}") self.page.goto(self.page_url, wait_until="domcontentloaded", timeout=30000) self.wait_for_page_load() def is_loaded(self): """检查页面是否加载完成""" return self.is_element_visible(self.SEARCH_INPUT) def search(self, keyword: str): """执行搜索""" logger.info(f"搜索关键词: {keyword}") self.fill_text(self.SEARCH_INPUT, keyword) self.click_element(self.SEARCH_BUTTON) return True ``` --- ### 步骤 2:创建测试用例 在 `tests/` 目录下创建测试文件,例如 `tests/test_home.py`: ```python import pytest from playwright.sync_api import Page from pages.home_page import HomePage from utils.logger import get_logger logger = get_logger(__name__) class TestHome: """首页测试类""" @pytest.fixture(autouse=True) def setup(self, page: Page): """测试前置设置""" self.page = page self.home_page = HomePage(page) @pytest.mark.smoke @pytest.mark.ui def test_search_functionality(self): """测试搜索功能""" logger.info("开始测试搜索功能") # 导航到首页 self.home_page.navigate() assert self.home_page.is_loaded(), "首页未正确加载" # 执行搜索 success = self.home_page.search("测试关键词") assert success, "搜索应该成功" logger.info("搜索功能测试通过") ``` --- ### 步骤 3:运行测试 ```bash pytest tests/test_home.py -v -s ``` --- ## ⚙️ 配置说明 ### 等待时间配置 框架采用多层级等待策略: | 层级 | 位置 | 超时时间 | 说明 | |------|------|----------|------| | **全局默认** | `conftest.py` 第 39 行 | 20 秒 | 所有元素操作 | | **导航超时** | `conftest.py` 第 40 行 | 30 秒 | 页面跳转 | | **元素等待** | `page_utils.py` 第 21 行 | 30 秒 | 等待元素可见 | | **元素检查** | `page_utils.py` 第 99 行 | 10 秒 | 检查元素可见性 | | **页面加载** | `base_page.py` 第 35 行 | 15 秒 | DOM 加载完成 | | **Alert 等待** | `my_login_page.py` 第 127 行 | 8 秒 | Alert 弹框 | ### 视频录制配置 - **成功测试**:视频自动删除(节省空间) - **失败测试**:视频自动保留(便于调试) - **配置位置**:`conftest.py` 第 64-74 行、第 97-111 行 ### 截图配置 - **失败时自动截图**:保存到 `reports/screenshots/` - **配置位置**:`conftest.py` 第 54-59 行 --- ## 💡 最佳实践 ### 1. 页面对象设计 ✅ **推荐**: - 每个页面创建一个页面对象类 - 继承 `BasePage` - 定义页面元素选择器为类常量 - 实现 `navigate()` 和 `is_loaded()` 方法 ❌ **不推荐**: - 在测试用例中直接使用选择器 - 重复定义相同的元素选择器 --- ### 2. 测试用例编写 ✅ **推荐**: - 使用 `@pytest.mark` 标记测试 - 使用 `setup` fixture 初始化页面对象 - 使用页面对象方法进行操作 - 使用清晰的断言消息 ❌ **不推荐**: - 在测试中直接操作 `page` 对象 - 硬编码测试数据 - 缺少断言 --- ### 3. 等待策略 ✅ **推荐**: - 使用显式等待(`wait_for_element`) - 使用页面加载指示器(`page_loaded_indicator`) - 使用 `domcontentloaded` 而不是 `networkidle`(更快) ❌ **不推荐**: - 使用 `time.sleep()` 硬等待 - 不等待页面加载完成就操作 --- ### 4. 异常处理 ✅ **推荐**: - 使用 `safe_click()`、`safe_fill()` 等安全方法 - 在页面对象中处理业务异常 - 使用日志记录错误信息 --- ## ❓ 常见问题 ### Q1: 测试运行很慢怎么办? **A**: 1. 确保使用 `headless=True`(后台运行) 2. 使用 `domcontentloaded` 而不是 `networkidle` 3. 减少不必要的等待时间 4. 使用并行执行:`pytest -n auto` --- ### Q2: 元素找不到怎么办? **A**: 1. 检查选择器是否正确 2. 增加等待时间 3. 使用 `wait_for_element()` 显式等待 4. 检查页面是否完全加载 --- ### Q3: 视频文件太多怎么办? **A**: - 框架已自动处理:成功测试的视频会自动删除 - 只有失败测试的视频会保留 - 可以手动清理:`rm reports/videos/*.webm` --- ### Q4: 如何调试测试? **A**: 1. 设置 `headless=False` 查看浏览器操作 2. 使用 `slow_mo` 参数减慢操作速度 3. 查看日志文件:`logs/test_YYYYMMDD.log` 4. 查看失败截图:`reports/screenshots/` 5. 查看失败视频:`reports/videos/` --- ### Q5: 如何并行运行测试? **A**: ```bash # 自动检测 CPU 核心数 pytest -n auto # 指定并行数 pytest -n 4 ``` --- ## 📞 技术支持 如有问题或建议,请联系 1693048789@qq.com --- ## 🎉 总结 这个框架提供了完整的 UI 自动化测试解决方案: - ✅ **清晰的架构** - POM 模式,易于维护 - ✅ **完善的工具** - 日志、配置、数据管理 - ✅ **自动化功能** - 视频、截图、报告 - ✅ **灵活的配置** - 多环境、多浏览器支持 - ✅ **详细的文档** - 完整的使用指南 **祝你测试愉快!** 🚀