第 22 章 · 生产实践:E2E 策略与报告
本章目标:把前 21 章的技术点收拢成一套可持续运营的 E2E 工程体系:分层策略、环境与数据管理、报告与告警、维护清单。
22.1 E2E 的定位:少而精,守关键路径
先校准认知:E2E 测试的单位成本是所有测试层里最高的(慢、易碎、难排查),它的价值在于验证"用户的关键旅程真的能走通",而不是追求覆盖率。健康的分层大致是:
| 层级 | 数量级 | 运行时机 | 职责 |
|---|---|---|---|
| 单元测试 | 数千 | 每次 push | 逻辑正确性(见本站 pytest 教程) |
| 接口/组件测试 | 数百 | 每次 PR | 服务契约、页面片段 |
| E2E 关键路径 | 20–50 条 | 每次 PR(冒烟)+ 每日全量 | 登录、下单、支付等核心旅程 |
据此把 E2E 再分三级,用 pytest marker 管理:
# pytest.ini 中注册标记
[pytest]
markers =
smoke: 冒烟集,PR 必跑(约 5 分钟内)
critical: 关键路径,合并前必跑
full: 全量回归,每日定时import pytest
@pytest.mark.smoke
def test_login(page):
...
@pytest.mark.critical
def test_place_order_end_to_end(page, login_as):
...pytest -m smoke # PR 流水线
pytest -m "critical or smoke" # 合并流水线
pytest -m full # 夜间全量22.2 环境与测试数据工厂
生产级 E2E 最常见的翻车点是数据。三条原则:
- 专用环境:永远不要对生产环境跑写操作;测试环境要能快速重置;
- 自造数据:每个测试自己创建所需数据,结束清理(或用一次性数据库快照);
- API 造数优先于 UI 造数:UI 造数慢且脆弱。
推荐"API 准备 + UI 验证"的分工模式:
import requests
import pytest
API = "https://api.staging.example.com"
@pytest.fixture
def product(api_token):
"""通过 API 创建一件商品,测试结束后删除——UI 只负责验证展示"""
resp = requests.post(
f"{API}/products",
json={"name": "测试商品-勿动", "price": 9.9},
headers={"Authorization": f"Bearer {api_token}"},
timeout=10,
)
product = resp.json()
yield product
requests.delete(f"{API}/products/{product['id']}",
headers={"Authorization": f"Bearer {api_token}"}, timeout=10)
def test_product_visible_in_storefront(page, product):
page.goto(f"https://staging.example.com/products/{product['id']}")
expect(page.get_by_role("heading", name=product["name"])).to_be_visible()配合第 9 章的 storage_state 复用登录态、第 13 章的参数化扩展数据维度,就能搭出稳定的数据底座。
22.3 报告:让结果可读、可追溯
pytest-playwright 本身不带 HTML 报告器,生产环境通常叠加一层报告插件:
pip install pytest-html # 轻量方案
pytest --html=report.html --self-contained-html需要失败截图自动嵌入时,结合 --screenshot only-on-failure 与 conftest 钩子把图片挂进报告。对更完整的"历史趋势 + 附件 + 步骤"需求,可选 Allure:
# pip install allure-pytest
import allure
@allure.feature("购物车")
@allure.story("添加商品")
def test_add_to_cart(page, product):
with allure.step("打开商品详情页"):
page.goto(f"https://staging.example.com/products/{product['id']}")
with allure.step("加入购物车并验证角标"):
page.get_by_role("button", name="加入购物车").click()
expect(page.get_by_test_id("cart-badge")).to_have_text("1")无论选哪个,CI 里必须保留的失败工件是三件套:trace.zip、截图、视频(第 11 章的 --tracing retain-on-failure 等 CLI 参数),它们是远程排错的唯一依据。
22.4 失败分类与告警
不要让所有失败都发出同一种噪音。按处理路径分类:
- A 类 · 产品 Bug:真实缺陷 → 建单修复,这是测试的价值所在;
- B 类 · 环境问题:服务宕了、证书过期 → 告警给运维,测试标重试;
- C 类 · 测试自身 Flaky:按第 19 章流程治理;
- D 类 · 预期变更:产品有意改动导致断言过期 → 更新测试并在 PR 说明。
告警设计上:smoke 集 PR 内失败直接阻塞合并;夜间全量的失败次日晨会通报,附报告链接与失败分类标签。目标是每一条红色都有归属人。
22.5 维护清单与上线检查单
每月维护清单:
- [ ] 重试率是否超过阈值(>1% 需专项治理)?
- [ ] 是否有用例运行时间超过 60 秒?考虑拆分或下沉到接口层
- [ ] Playwright / 浏览器内核版本是否落后超过一个大版本?
- [ ] storage_state、fixture 中的账号权限是否仍有效?
功能上线前的 E2E 检查单:
- [ ] 新关键路径已有对应
critical用例; - [ ] 新增页面元素使用了稳定的
data-testid(前端联调约定); - [ ] 涉及 WS/轮询的实时功能有消息层断言(第 21 章);
- [ ] 无障碍结构断言已更新(第 20 章);
- [ ] 测试数据可通过 API 一键构造与清理。
22.6 本章小结
- E2E 少而精:smoke/critical/full 三级标记,分别绑定 PR、合并、夜间流水线;
- 数据三原则:专用环境、自造自清、API 造数 UI 验证;
- 报告选型:
pytest-html轻量起步,Allure 要步骤与趋势;trace/截图/视频是必备失败工件; - 失败四分类(Bug/环境/Flaky/预期变更),每条红色必须有归属人;
- 用月度维护清单和上线检查单让体系持续健康。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. 关于 E2E 测试在生产实践中的定位,符合本章观点的是?
2. "API 造数 + UI 验证"分工的好处不包括?
3. 一次夜间全量失败,排查发现是测试环境的 TLS 证书过期。这属于哪类失败?
4. CI 中 E2E 失败时,最应该保留的工件组合是?
🛠️ 动手实践
- 为你现有的 E2E 套件打上
smoke/critical/full三级标记,统计每级的用例数与耗时,写出你的分级依据。 - 把一个目前靠页面上点点点准备数据的用例改造成 API fixture 造数,对比改造前后耗时与稳定性。
- 搭一条最小的 GitHub Actions 流水线:PR 触发
-m smoke,失败时上传 trace/截图工件并留评论。
🎉 恭喜完成全部 22 章!返回课程导学复盘学习路线,或继续本站其他教程。