构建高内聚低耦合的 Playwright UI 自动化测试架构
环境初始化与依赖管理
搭建基于 Python 的 Web UI 自动化测试平台,核心依赖于 Playwright 进行浏览器操作,Pytest 作为测试执行引擎,YAML 用于配置数据驱动,Allure 生成可视化报告。首先需在开发环境中安装必要的第三方库。
pip install pyyaml playwright allure-pytest pytest pytest-playwright
playwright install chromium
此外,需从官方 Maven 仓库下载 Allure Commandline 工具并配置至系统环境变量中,以支持报告的生成与浏览。
项目目录结构规划
遵循分层设计原则,将代码按功能职责进行划分,确保各模块间的低耦合性。标准工程结构如下:
├── common # 公共组件层
│ ├── action.py # 基础交互封装
│ ├── report.py # 异常截图与报告关联
│ └── config.py # 配置读取逻辑
├── tests # 测试用例层
│ ├── conftest.py # Pytest 钩子函数
│ └── test_core.py# 业务场景脚本
├── data # 测试数据层
│ └── scenario.yaml
├── logs # 日志输出目录
├── reports # Allure 报告存放区
└── main.py # 启动入口
公共组件层实现
1. 基础交互封装 (action.py)
提取高频使用的 DOM 操作,如定位、点击及输入,减少重复代码量。
from playwright.sync_api import Page
def execute_interact(page_obj: Page, selector: str, text_content: str):
"""
统一处理元素定位与填充操作
:param page_obj: 页面句柄
:param selector: CSS 选择器或 XPath
:param text_content: 待填入文本
"""
element = page_obj.locator(selector)
element.click()
element.fill(text_content)
2. 结果捕获与关联 (report.py)
在测试失败或关键节点时截取屏幕图像,并嵌入到 Allure 报告中。
import os
import allure
from playwright.sync_api import Page
def capture_snapshot(ctx_page: Page, save_dir: str, report_id: str):
filepath = f"{save_dir}{report_id}.png"
ctx_page.screenshot(path=filepath)
with open(filepath, 'rb') as img_file:
allure.attach(img_file.read(), name=report_id, attachment_type=allure.attachment_type.PNG)
os.remove(filepath) # 可选:清理临时文件
3. 配置文件加载 (config.py)
使用 PyYAML 解析外部数据文件,实现测试数据与脚本分离。
import yaml
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
def load_yaml_data(file_name: str) -> dict:
file_path = BASE_DIR / "data" / file_name
with open(file_path, encoding='utf-8') as stream:
return yaml.safe_load(stream)
测试用例层设计
1. Pytest 钩子配置 (conftest.py)
利用 Hook 机制动态向 Allure 报告注入用例元数据(如特性名称和标题)。
import allure
from _pytest.nodes import Node
def pytest_runtest_call(item: Node):
func_doc = item.function.__doc__
parent_doc = getattr(getattr(item.parent, '_obj', None), '__doc__', '')
if parent_doc:
allure.dynamic.feature(parent_doc)
if func_doc:
allure.dynamic.title(func_doc)
2. 业务场景脚本 (test_core.py)
具体测试逻辑应清晰描述业务步骤,调用公共方法处理细节。
import pytest
import allure
from common.action import execute_interact
from common.report import capture_snapshot
from common.config import load_yaml_data
from playwright.sync_api import Page
@allure.epic("Web 搜索验证")
@allure.title("关键词检索功能测试")
def test_keyword_lookup(page: Page):
doc = """验证百度首页搜索框的准确性"""
# 注入文档字符串以适配 Allure
test_keyword_lookup.__doc__ = doc
config_data = load_yaml_data("scenario.yaml")
search_cfg = config_data.get("search_case")
page.goto(search_cfg["url"])
execute_interact(page, search_cfg["input_selector"], search_cfg["keyword"])
page.get_by_role("button", name=search_cfg["submit_text"]).click()
capture_snapshot(page, search_cfg["img_path"], search_cfg["report_name"])
@allure.epic("Web 搜索验证")
@allure.title("特定技术词检索")
def test_playwright_search(page: Page):
page.goto("https://www.baidu.com/")
execute_interact(page, "#kw", "playwright")
page.get_by_role("button", name="百度一下").click()
capture_snapshot(page, "./logs/screenshots/", "pw_check")
数据驱动层 (Data)
所有可变参数存入 YAML 文件,便于非技术人员维护或进行环境切换。
# data/scenario.yaml
search_case:
url: https://www.baidu.com/
input_selector: "#kw"
keyword: pytest
submit_text: 百度一下
img_path: ./logs/screenshots/
report_name: pytest_result
运行配置与报告生成
1. 框架配置 (pytest.ini)
[pytest]
addopts = -v --alluredir=./reports/temp --clean-alluredir
testpaths = tests
python_files = test_*.py
python_functions = test_*
markers =
smoke: 标记为冒烟测试
2. 启动脚本 (main.py)
整合测试执行与报告发布流程,提供一键运行能力。
import subprocess
import sys
def run_tests():
exit_code = subprocess.call([sys.executable, "-m", "pytest"])
# 生成静态报告
subprocess.call(["allure", "generate", "./reports/temp", "-o", "./reports/final", "--clean"])
# 本地开启报告服务器查看
subprocess.Popen(["allure", "serve", "./reports/temp"])
return exit_code
if __name__ == "__main__":
sys.exit(run_tests())
分层设计的核心价值
采用模块化分层架构主要基于以下考量:
- 维护效率:若仅需变更登录地址,只需修改配置层,无需遍历数百个用例代码。
- 扩展性:新增公共行为(如等待加载、右键菜单)时,仅在 Common 层添加,所有用例复用。
- 数据解耦:测试数据与逻辑代码分离,便于进行数据驱动测试(DDT),应对不同测试集。
- 可读性:清晰的目录结构使新成员能快速理解项目脉络,降低协作沟通成本。