第 16 章 · CI 集成与 Docker
本章目标:把 E2E 套件跑进 GitHub Actions,用官方容器保证环境一致性,并在失败时自动留存 trace 等诊断工件。
16.1 CI 三步走
官方把 CI 接入总结为三步:
- 让 CI 机器能跑浏览器——Linux 上用官方 Docker 镜像,或用 CLI 装系统依赖;
- 安装 Playwright——
pip install playwright && playwright install --with-deps; - 跑测试——
pytest。
其中 --with-deps 会顺带装好操作系统级依赖库(libnss3 等),漏掉它是"本地能跑、CI 报缺库"的头号原因。
16.2 GitHub Actions 基础工作流
官方示例工作流(Python 版):
# .github/workflows/playwright.yml
name: Playwright Tests
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Ensure browsers are installed
run: python -m playwright install --with-deps
- name: Run your tests
run: pytest --tracing=retain-on-failure # 失败时保留 trace
- name: Upload traces # 无论成败都上传工件
uses: actions/upload-artifact@v5
if: ${{ !cancelled() }}
with:
name: playwright-traces
path: test-results/两个细节值得咀嚼:
--tracing=retain-on-failure是 pytest-playwright 提供的开关:只有失败用例才落盘 trace,成功的不浪费空间;- 上传工件的
if: ${{ !cancelled() }}保证即使有测试失败、工作流被判定失败,trace 也照样传出来——否则你只能看到红叉看不到证据。
16.3 用官方容器获得一致环境
宿主机环境漂移(字体、时区、依赖版本)会让截图类断言莫名失败。官方镜像 mcr.microsoft.com/playwright/python 内置了全部浏览器和系统依赖,把 job 直接跑在容器里:
jobs:
playwright:
timeout-minutes: 60
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright/python:v1.61.0-noble # 版本要与 pip 安装的 playwright 匹配
options: --user 1001 # 非 root 运行更安全
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r local-requirements.txt
pip install -e .
- name: Run your tests
run: pytest版本对齐
镜像 tag 里的 Playwright 版本必须与你 pip install 的 playwright 大版本一致(如都用 1.61/1.62),否则驱动协议不匹配会直接报 executable 不存在或协议错误。镜像只含浏览器不含 Python 包,pip install playwright 仍需执行。
加速:两层缓存
- pip 缓存:
actions/setup-python自带cache: pip; - 浏览器缓存:非容器方案下缓存
~/.cache/ms-playwright目录,key 中带上 playwright 版本号,命中后跳过上百 MB 的下载。
16.4 本地 Docker 运行要点
想在容器里手动调试(或自建 runner),记住三个官方推荐参数:
# E2E 测试属于可信代码,可直接 root 运行(root 下 Chromium 自动禁用沙箱)
docker run -it --rm --init --ipc=host \
mcr.microsoft.com/playwright/python:v1.61.0-noble /bin/bash
# 爬取不可信网站时:改用独立用户 + seccomp 配置启用沙箱
docker run -it --rm --ipc=host \
--user pwuser \
--security-opt seccomp=seccomp_profile.json \
mcr.microsoft.com/playwright/python:v1.61.0-noble /bin/bash--ipc=host:Chromium 共享内存需求大,默认 64MB 的 IPC 分区会导致浏览器随机 OOM 崩溃——这是 Docker 跑 Chromium 最经典的坑;--init:避免 PID=1 进程的特殊处理产生僵尸进程;--cap-add=SYS_ADMIN:本地开发遇到奇怪的启动报错时可先加上排查(沙箱权限问题)。
16.5 失败诊断的完整闭环
CI 里一条用例挂了,理想的信息链是:
JUnit/终端输出(哪条挂了) → HTML 报告(步骤截图) → trace.zip(逐步回放+网络+控制台)pytest 侧的对应产出:
pytest \
--junitxml=results/report.xml \ # CI 系统聚合展示
--html=results/report.html \ # pytest-html 插件:带每步截图的静态报告
--screenshot=only-on-failure \ # pytest-playwright:失败截图到 test-results/
--video=retain-on-failure \ # 失败录像
--tracing=retain-on-failure # 失败 trace(第 11 章的 Trace Viewer 打开)注意区分:Node 版 Playwright 有内置 HTML Reporter,而 Python/pytest 生态中 HTML 报告由第三方 pytest-html 提供,--tracing/--video/--screenshot 则是 pytest-playwright 插件的选项——两者职责不同,常配合使用。
16.6 本章小结
- CI 三步:装浏览器依赖 → 装 Playwright →
pytest;install --with-deps别省; - 官方容器镜像保证环境一致,tag 版本必须与 pip 包对齐;容器内记得
--ipc=host与--init; --tracing=retain-on-failure+upload-artifact(if: !cancelled())构成失败取证闭环;- Python 生态的 HTML 报告来自 pytest-html,trace 才是最强证据。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. CI 上报错缺少 libnss3 等系统库,最直接的解法是?
2. 上传失败 trace 的 step 为什么要加 if: !cancelled()?
3. Docker 里运行 Chromium 必须加 --ipc=host 的原因是?
4. 关于官方容器镜像 mcr.microsoft.com/playwright/python,说法正确的是?
🛠️ 动手实践
- 给你的仓库写一份完整的
playwright.yml,包含 pip 与浏览器目录双层缓存,并实际触发一次运行。 - 故意让一条用例失败,从 Artifacts 下载 trace 并用
playwright show-trace回放定位原因。 - 用官方镜像在本地起容器跑通你的套件,对比去掉
--ipc=host后是否出现浏览器崩溃。