目录

Python 自动化测试框架

基于 Playwright + Pytest 的自动化测试框架,采用 Python 原生脚本编写测试用例,支持 Allure 和 Pure 两种测试报告。

核心特性

  1. Python 脚本驱动: 仅支持通过 Python 原生脚本编写测试用例,直接使用 Playwright 的 page 对象,灵活度更高
  2. 双报告引擎: 支持 Allure 报告和 Pure 报告(HTML 单文件,离线可看),通过 -r 参数切换
  3. 自动日志: 通过 loguru 记录运行日志,Pure 报告自动收集 setup/call/teardown 三阶段日志并合并展示
  4. 截图、录屏与 Trace:
    • 截图支持三种范围(never / fail_only / always),在测试结束后通过 hook 触发,可按结果决定
    • 录屏支持两种范围(never / always),在 context 创建时配置(Playwright 限制,无法按结果决定)
    • Trace 支持三种范围(never / fail_only / always),按用例级别录制,每个用例独立 zip,通过 Playwright Trace Viewer 可视化回放
  5. 会话管理: 支持认证会话保存和复用,避免重复登录
  6. 时间戳目录: 每次运行生成独立的报告目录(含报告、截图、录屏、trace),便于追溯历史运行
  7. 极简编写: 直接使用 Playwright 的 page 对象,配合 allure.step 或 pure.step 记录步骤

框架目录结构

automation_framework/
├── config/                       # 配置目录
│   ├── __init__.py
│   └── settings.py              # 全局配置文件
├── tests/                       # 测试用例目录(Python 脚本)
│   ├── __init__.py
│   ├── conftest.py              # Pytest 配置和 Fixtures(浏览器、登录会话等)
│   ├── auth/                    # 登录与注册模块用例
│   └── user_settings/           # 用户设置模块用例
│       ├── helpers.py           # 用户设置模块公共辅助(路由、引导弹窗、文本断言等)
│       └── ...
├── utils/                       # 工具类目录
│   ├── __init__.py
│   ├── log_tools.py             # 日志初始化(loguru 配置)
│   └── auth_session.py          # 认证会话管理
├── lib/                         # 内置第三方库
│   └── allure-2.22.0/          # Allure 命令行工具
├── outputs/                     # 输出目录(运行后自动生成)
│   ├── logs/                    # 运行日志(每次运行一个独立日志文件)
│   ├── pure_reports/            # Pure 报告根目录(按时间戳分子目录)
│   └── allure_reports/          # Allure 报告根目录(按时间戳分子目录)
├── run.py                       # 测试运行入口
├── pytest.ini                   # pytest 配置
├── requirements.txt             # Python 依赖
├── Dockerfile                   # Docker 镜像配置
└── README.md                    # 项目说明

配置文件说明

config/settings.py

配置项 说明 默认值
报告配置
REPORT_TYPE 报告类型 (allure/pure) pure
REPORT_TITLE 报告标题 自动化测试报告
REPORT_ENV 测试环境标识 (test/dev/prod) test
REPORT_FILENAME 报告文件名(None 表示默认时间戳) None
PURE_REPORTS_ROOT Pure 报告根目录 outputs/pure_reports
ALLURE_REPORTS_ROOT Allure 报告根目录 outputs/allure_reports
ALLURE_BIN Allure 可执行文件路径 自动识别(优先本地安装)
截图 / 录屏 / Trace
SCREENSHOT_SCOPE 截屏范围 (never/fail_only/always) fail_only
VIDEO_SCOPE 录屏范围 (never/always)。Playwright 录屏在测试前配置,无法按结果决定 never
TRACE_SCOPE Trace 范围 (never/fail_only/always)。按用例级别录制,每个用例独立 zip never
浏览器配置
BROWSER_TYPE 浏览器类型 (chromium/firefox/webkit) chromium
HEADLESS 是否无头模式 True
BROWSER_WIDTH 浏览器窗口宽度 1920
BROWSER_HEIGHT 浏览器窗口高度 1080
BROWSER_TIMEOUT 浏览器启动超时(秒) 30
测试目标
BASE_URL 测试网站地址 http://172.20.32.195:8000
测试用户
TEST_USER_USERNAME 测试用户账号 floraachy
TEST_USER_PASSWORD 测试用户密码 12345678
TEST_USER_DISPLAY_NAME 测试用户显示名称 floraachy
PROJECT_MEMBER_USERNAME 项目协作成员用户名(用于”添加/删除成员”用例,需为已注册用户) 空(默认用自身)
其他
OUTPUTS_DIR 输出目录根路径 outputs/
LOG_PATH 日志存放路径 outputs/logs/
AUTH_DIR 认证会话存储目录 .auth/

Allure 路径配置

框架支持两种 Allure 路径配置方式:

  1. 本地安装:设置环境变量 ALLURE_HOME 指向 Allure 安装目录
  2. 项目内置:默认使用 lib/allure-2.22.0/bin/ 下的 Allure
# 方式1: 设置环境变量(Windows)
set ALLURE_HOME=C:\allure-2.22.0

# 方式2: 使用项目内置 Allure(无需配置)
python run.py

配置数据流

截图/录屏/Trace 配置的读取优先级(从高到低):

命令行参数  >  settings.py 默认值
     ↓
run.py 合并后注入环境变量
     ↓
conftest.py / plugin.py 读取环境变量

截图、录屏与 Trace 的差异:

  • 截图:在测试结束后通过 pytest hook 触发,可以按测试结果(通过/失败)决定是否截图,支持 fail_only 模式
  • 录屏:在浏览器 context 创建时配置(Playwright 限制),测试执行前就必须决定是否开启,无法按结果决定,因此不支持 fail_only 模式
  • Trace:在用例前启动 context.tracing.start(),用例后停止并保存为 zip,可按用例结果决定是否保留,支持 fail_only 模式

截图、录屏与 Trace 配置

框架对截图、录屏和 Trace 采用不同的触发机制,配置范围也有所不同:

截图(SCREENSHOT_SCOPE)

截图在测试结束后通过 pytest_runtest_makereport hook 触发,此时测试结果(通过/失败)已知,可以按结果决定是否截图。

范围 说明 使用场景
never 不截图 快速验证、CI 流水线
fail_only 仅测试失败时截图(默认) 日常测试,排查失败用例
always 每次测试都截图 需要完整审计追踪

录屏(VIDEO_SCOPE)

录屏在浏览器 context 创建时配置(Playwright API 限制),测试执行前就必须决定是否开启,无法提前预知测试结果。

范围 说明 使用场景
never 不录屏(默认) 快速验证、CI 流水线、节省资源
always 每次测试都录屏 复杂交互调试、需要完整回放

为何录屏不支持 fail_only? Playwright 的录屏通过 record_video_dir 在 browser.new_context() 时配置,必须测试前就决定是否开启。测试执行时才能知道结果,但录屏早已启动,无法回溯关闭。 如需失败证据,请使用 SCREENSHOT_SCOPE=fail_only,截图在测试后触发,可按结果决定。

Trace(TRACE_SCOPE)

Trace 在每个用例前后通过 context.tracing.start() / context.tracing.stop() 录制,每个用例独立一个 zip 文件,可按用例结果决定是否保留。

范围 说明 使用场景
never 不录制 trace(默认) 快速验证、CI 流水线
fail_only 仅失败用例保留 trace 日常测试,精准定位失败用例
always 每个用例都保留 trace 完整审计、复杂交互回放

Trace 优势:相比录屏,Trace 包含更丰富的调试信息(页面快照、DOM 树、网络请求、控制台日志、操作源码位置),且支持前后穿梭于每个操作;相比截图,Trace 记录了完整的操作过程而非单一时间点。

按用例录制:每个用例独立一个 trace zip 文件,便于精准定位失败用例的问题,文件体积小,便于分享。

配置方式

方式1:修改 settings.py 默认值

# config/settings.py
SCREENSHOT_SCOPE = "fail_only"  # never / fail_only / always
VIDEO_SCOPE = "never"           # never / always
TRACE_SCOPE = "never"           # never / fail_only / always

方式2:命令行参数覆盖(优先级更高)

# 仅失败时截图和 trace,不录屏
python run.py --screenshot fail_only --video-scope never --trace-scope fail_only

# 全量截图录屏 trace(调试用)
python run.py --screenshot always --video-scope always --trace-scope always

# 不截图不录屏不 trace(最快)
python run.py --screenshot never --video-scope never --trace-scope never

如何编写测试用例

本框架仅支持 Python 脚本写法。在 tests/ 下新建 test_*.py 文件,直接使用 Playwright 的 page 对象,配合 allure.step / pure.step 和 loguru 记录测试步骤与日志。

import pytest
import allure
from loguru import logger
from pytest_pure_report import pure
from config.settings import BASE_URL, TEST_USER_USERNAME, TEST_USER_PASSWORD
import utils.log_tools  # noqa: F401 - 触发 loguru 初始化(配置控制台/文件处理器)

@allure.feature("用户登录")
class TestLoginScript:

    @allure.story("登录成功")
    def test_login_success(self, page):
        """测试登录成功场景"""
        with allure.step(f"打开登录页面:{BASE_URL}/login"):
            logger.info(f"打开登录页面: {BASE_URL}/login")
            page.goto(f"{BASE_URL}/login", wait_until="networkidle")

        with allure.step("输入用户名和密码"):
            logger.info(f"输入用户名: {TEST_USER_USERNAME}")
            page.fill('input[placeholder="请输入手机号/用户名"]', TEST_USER_USERNAME)
            page.fill('input[placeholder="请输入登录密码"]', TEST_USER_PASSWORD)

        with allure.step("点击登录按钮"):
            logger.info("点击登录按钮")
            page.click("button:has-text('登 录')")

        with allure.step("验证登录成功"):
            page.wait_for_selector(".currentImg", timeout=10000)

使用认证会话管理

框架提供认证会话管理功能,可以在测试间复用登录状态:

def test_with_auth(page, auth_session):
    # 应用已保存的会话(自动登录)
    auth_session.apply_session(page.context)

    # 访问需要登录的页面
    page.goto("/dashboard")
    assert page.locator(".user-info").is_visible()

快速开始

1. 环境准备

创建虚拟环境:

python -m venv venv
source venv/bin/activate  # Linux/Mac
venv\Scripts\activate     # Windows

安装依赖:

pip install -r requirements.txt
playwright install

2. 运行测试

# 默认运行(按 settings.py 配置的 REPORT_TYPE 生成报告)
python run.py

# 指定 Pure 报告
python run.py -r pure

# 指定 Allure 报告 + 无头模式 + 过滤 login 关键词
python run.py -r allure --headless true -k login

命令行参数

参数 说明 示例
-r, --report-type 报告类型 (allure/pure),默认 pure python run.py -r pure
-b, --browser-type 浏览器类型 (chromium/firefox/webkit),默认 chromium python run.py -b firefox
--headless 是否无头模式 (true/false),默认 true python run.py --headless false
-k, --keyword 按测试名称关键词过滤 python run.py -k login
--screenshot 截屏范围 (never/fail_only/always),默认 always python run.py --screenshot fail_only
--video-scope 录屏范围 (never/always),默认 never。Playwright 录屏在测试前配置,无法按结果决定 python run.py --video-scope always
--trace-scope Trace 范围 (never/fail_only/always),默认 never。按用例级别录制,每个用例独立 zip python run.py --trace-scope always

使用示例:

# Pure 报告 + 无头模式 + 不截图不录屏不 trace(快速验证)
python run.py -r pure --headless true --screenshot never --video-scope never --trace-scope never

# Allure 报告 + Firefox 浏览器 + 过滤 login 关键词
python run.py -r allure -b firefox -k login

# 全量截图录屏 trace(调试时)
python run.py -r pure --screenshot always --video-scope always --trace-scope always

# 仅失败用例保留 trace(日常测试推荐)
python run.py -r pure --trace-scope fail_only

3. Docker 运行

构建镜像:

docker build -t test-frame .

运行容器(结果挂载到本地):

docker run -v $(pwd)/outputs:/app/outputs test-frame

报告查看

Pure 报告

运行结束后,进入 outputs/pure_reports/<时间戳>/ 目录,直接用浏览器打开其中的 .html 文件即可查看报告(单文件,离线可看)。

报告目录结构:

outputs/pure_reports/<时间戳>/
├── test_report_*.html          # Pure 报告(HTML 单文件)
├── screenshots/                # 截图文件
├── videos/                     # 录屏文件
├── traces/                     # Trace zip 文件(按用例分子目录)
│   └── test_login_success/
│       └── test_login_success_*.zip
└── trace-viewer/               # Playwright Trace Viewer SPA(由 run.py 自动复制)
    ├── index.html
    └── ...

查看 Trace:报告内每个用例卡片下方会显示「Trace 记录」区段(仅当该用例有 trace 文件时显示),点击「查看 Trace」按钮会在新标签页打开 Playwright Trace Viewer。

注意:Trace Viewer 依赖 Service Worker,必须通过 HTTP 协议访问,不能直接用 file:// 打开。需要在报告目录启动 HTTP 服务器:

cd outputs/pure_reports/<时间戳>
python -m http.server 8000
# 然后浏览器访问 http://localhost:8000/test_report_<时间戳>.html

Allure 报告

运行结束后,进入 outputs/allure_reports/<时间戳>/allure_report/ 目录,打开 index.html 查看报告。

或使用 Allure 命令行启动本地服务:

allure serve outputs/allure_reports/<时间戳>/allure_results

Pure 报告特性

Pure 报告通过 pytest-pure-report 插件生成,主要特性:

  1. 离线可看:HTML 单文件,无需启动服务,浏览器直接打开
  2. 日志合并:自动收集 setup/call/teardown 三阶段日志,合并展示在后置处理后
  3. 媒体智能展示:无截图/录屏/trace 时对应区域不显示;有则按用例名自动匹配
  4. Trace 集成:开启 trace 后,每个用例卡片下显示「Trace 记录」区段,点击「查看 Trace」跳转到 Playwright Trace Viewer 页面
  5. 扩展区段:支持通过 pure.step() 添加自定义步骤、附件等

Pure 报告 API

Pure 报告完全参考 allure 的 API 设计,业务侧代码无需修改即可在 Pure 报告模式下工作(框架已通过 patch_allure() 自动委托)。

步骤(上下文管理器 / 装饰器)

from pytest_pure_report import pure

# 上下文管理器(自动捕获异常状态:passed/failed/broken)
with pure.step("打开登录页面"):
    page.goto("/login")

# 装饰器(自动提取函数参数作为步骤参数展示)
@pure.step("输入用户名和密码")
def fill_credentials(page, username, password):
    page.fill("#username", username)
    page.fill("#password", password)

附件

# 文本附件
pure.attach("hello world", name="问候", attachment_type=pure.attachment_type.TEXT)

# 文件附件(如截图)
pure.attach.file("screenshots/login.png", name="登录截图")

断言记录(Pure 扩展,allure 无此功能)

与原生 assert 配合,在报告中展示断言的预期值/实际值对比:

assert page.title() == "GitLink"
pure.record_equal(page.title(), "GitLink", "验证页面标题")

pure.record_contains(resp.text, "success", "验证响应包含 success")

pure.record_visible(page.locator(".avatar").is_visible(), "验证用户头像可见")

标签装饰器(与 allure 完全一致)

@pure.feature("登录")
@pure.story("成功登录")
@pure.severity(pure.severity_level.CRITICAL)
@pure.tag("smoke")
@pure.title("验证用户使用正确账号可以登录")
def test_login_success(page):
    ...

运行时动态信息

def test_something(page):
    pure.dynamic.title("动态标题")
    pure.dynamic.tag("dynamic-tag")
    pure.dynamic.severity(pure.severity_level.BLOCKER)

API 一览

API 作用
pure.step(title) 步骤(装饰器 + 上下文管理器,自动捕获状态)
pure.fixture(name) fixture 装饰器(自动追踪 setup/teardown)
pure.attach(body, ...) 添加内联内容附件
pure.attach.file(source, ...) 添加文件附件
pure.record(...) 记录断言结果(通用 API)
pure.record_equal(...) 便捷方法:相等断言
pure.record_contains(...) 便捷方法:包含断言
pure.record_visible(...) 便捷方法:元素可见性断言
pure.title/description/feature/story/... 装饰器:标签
pure.dynamic 运行时动态修改标题/标签等
pure.severity_level 严重级别常量(BLOCKER/CRITICAL/NORMAL/MINOR/TRIVIAL)
pure.attachment_type 附件类型常量(TEXT/JSON/PNG/…)

常用命令

# 使用 run.py 运行(推荐,自动生成报告)
python run.py -r pure -k login

# 按模块过滤运行(-k 匹配目录/文件/用例名关键词)
python run.py -r pure -k user_settings   # 用户设置模块
python run.py -r pure -k auth            # 登录与注册模块

# 直接使用 pytest 运行(调试用,禁用报告插件,不生成报告)
pytest tests/ -v -p no:pytest-pure-report -p no:allure_pytest

# 运行特定模块
pytest tests/user_settings/ -v -p no:pytest-pure-report

# 运行单个用例
pytest tests/auth/test_login.py::TestLoginSuccess::test_login_by_username -v -p no:pytest-pure-report
关于

兼容 Python 脚本编写 和 YAML 数据驱动 两种模式的自动化测试框架。

369.3 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号