Skip to content

第 1 章 · E2E 测试与 Playwright 概述

本章目标:理解 E2E 测试在测试金字塔中的位置,搞清 Playwright 相比 Selenium 的架构优势,装好 Playwright 并跑通环境。

1.1 测试金字塔中的 E2E

经典的测试金字塔从下到上分为三层:

层级数量速度稳定性验证内容
单元测试最多毫秒级极稳函数/类的逻辑
集成测试适中秒级较稳模块协作、数据库、API
E2E 测试最少十秒级易碎真实浏览器里的完整用户旅程

E2E(End-to-End,端到端)测试模拟的是"真实用户打开浏览器 → 操作页面 → 看到结果"的全过程。它慢且贵,但只有它能回答一个问题:用户实际用起来到底行不行。所以生产实践的原则是"少而精"——只覆盖关键路径(登录、下单、支付),而不是把所有分支都搬进来。

本教程的定位

本站 pytest 教程讲的是金字塔下半部分;本课程专注最顶层。两门课共用同一套 pytest 知识体系,第 6 章起会大量复用 fixture 技能。

1.2 Selenium WebDriver vs Playwright:架构决定体验

老一代方案 Selenium WebDriver 的工作方式是"外部遥控":

text
测试代码 → HTTP 请求 → WebDriver 驱动进程 → 浏览器扩展注入 JS → 页面

每一步操作都要跨进程通信,且驱动不知道页面何时渲染完成,只能靠人肉 time.sleep(3) 或显式等待补救——这是 Selenium 时代测试易碎(flaky)的根源。

Playwright 的做法完全不同:测试进程通过直连浏览器的协议管道(Chromium 用 CDP,Firefox/WebKit 用补丁版内核内建协议)与浏览器对话:

text
测试代码 ←同一条持久连接→ 浏览器内核
         (事件驱动,双向推送)

这带来三个质变:

  • :没有中间驱动层,操作直接下达给内核;
  • 自动等待:内核知道页面的真实状态,Playwright 能在元素"可见、稳定、可交互"之前自动阻塞;
  • 事件可靠click 是真实的输入事件而非 JS 合成事件,还能监听网络、控制台等内核级信号。

1.3 三大浏览器内核

Playwright 支持 All modern rendering engines:

  • Chromium——Chrome/Edge 的内核,日常默认;
  • Firefox——打补丁的版本,可被自动化协议精确驱动;
  • WebKit——Safari 的内核,在 Linux/Windows 上也能测 Safari 行为。

一套 API 跑三个引擎,意味着你在 Linux CI 上就能覆盖 Safari 兼容性,不再需要 Mac 机器农场。

1.4 同步与异步双 API

Playwright Python 同时提供 sync_apiasync_api 两套镜像 API:

python
# 同步风格:直观,适合脚本和大多数测试
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("https://example.com")
    print(page.title())
    browser.close()
python
# 异步风格:适合 asyncio 应用和高并发爬取/压测场景
import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        await page.goto("https://example.com")
        print(await page.title())
        await browser.close()

asyncio.run(main())

两套 API 功能完全对等,异步版只是每个方法多了 await。前半程课程以同步为主,第 18 章专门讲异步。

1.5 安装与环境验证

bash
# 安装库本体
pip install playwright

# 下载三大内核(一次即可,约几百 MB)
playwright install

# 可选:安装系统依赖(Linux 常需要)
playwright install-deps

验证安装是否成功:

bash
playwright --version
# Version 1.62.x

再跑一个最小冒烟脚本 smoke.py

python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://example.com")
    assert "Example Domain" in page.title(), "标题不符合预期"
    print("✅ 环境正常,标题:", page.title())
    browser.close()
bash
python smoke.py
# ✅ 环境正常,标题: Example Domain

版本对应关系

playwright pip 包与浏览器内核是配套锁定的:升级 pip 包后必须重新执行 playwright install 下载新版本内核,否则会报找不到可执行文件的错误。

1.6 本章小结

  • E2E 位于测试金字塔顶端:少而精,只测关键用户路径;
  • Playwright 直连浏览器内核协议,相比 Selenium 更快、自动等待、事件更真实;
  • 一套 API 覆盖 Chromium / Firefox / WebKit 三大内核;
  • 提供 sync_api / async_api 两套对等 API;
  • 升级 Playwright 后记得重跑 playwright install

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. Playwright 与 Selenium WebDriver 最本质的架构差异是?

2. 想在 Linux CI 上验证 Safari 兼容性,应该用哪个内核?

3. 升级 playwright pip 包后运行报"找不到浏览器可执行文件",原因是?

4. 关于 sync_api 和 async_api,下列说法正确的是?

🛠️ 动手实践

  1. 用同步 API 写一个脚本,依次访问 example.complaywright.dev,分别打印 <title>
  2. 把第 1 题改写成异步版本,对比两种写法的差异。
  3. 分别用 headless 和 headed(headless=False)模式运行你的脚本,观察区别;再加 slow_mo=1000 感受慢放效果。

环境就绪后,进入第 2 章:第一个脚本与同步 API