1. 简介

Playwright 是微软开源的端到端(end-to-end)测试框架,可用于现代 Web 应用。Playwright 提供如下特性:


2. 本文测试环境


3. 安装

3.1. 创建测试环境

3.2. 添加样例测试

在当前工作目录或子目录内部,创建 test_my_application.py 文件,其内容如下:

3.3. 运行样例测试

在默认情况下,测试运行在 Chromium 上,可通过 CLI 选项进行配置,测试以 Headless 模式运行。测试结果和测试日志被展示在终端中。


4. 编写测试

Playwright 断言(assertion)是专门为动态网页创建的。检查将自动重试,直到满足必要的条件。Playwright 自带 auto-wait,这意味着它在执行操作前,等待到元素变为可操作的(actionable)。Playwright 提供 expect 函数来编写断言。

下面是展示如何编写使用断言、定位器(locator)和选择器(selector)的测试的示例。

4.1. 断言

Playwright 提供 expect 函数,它将一直等待,直到满足预期条件。

4.2. 定位器

定位器(Locator)是 Playwright 的自动等待和重试能力的核心部分。定位器是一种随时在网页上查找元素的方法,用于在元素上执行诸如 .click.fill 之类的操作。可以使用 page.locator(selector, **kwargs) 方法创建自定义定位器。

选择器(Selector)是用于创建定位器的字符串。Playwright 支持许多不同的选择器,比如 TextCSSXPath 等。阅读 in-depth guide 文档,了解更多关于可用的选择器以及如何进行选择的信息。

4.3. 测试隔离

Playwright Pytest 插件基于 test fixture(比如 built in page fixture)的概念,它将被传给你的测试。由于浏览器上下文,在测试之间,页面(Page)彼此隔离,这相当于开启新的浏览器行为,每个测试获得新环境,即使在一个浏览器中运行多个测试时,也是如此。

4.4. 使用测试钩子

可以使用各种各样的 fixture 在测试之前或之后执行代码,以及在它们之间共享对象。函数(function)作用域的 fixture 具有 beforeEach/afterEach 一样的自动使用行为。模块(module)作用域的 fixture 具有 beforeAll/afterAll 一样的自动使用行为,它在所有测试之前和所有测试之后运行。


5. 运行测试

可以运行单个测试、一组测试或全部测试。测试可以运行在一种或多种浏览器上。默认情况下,以 Headless 方式运行测试,这意味着在运行测试时,不会打开浏览器窗口,可以在终端中看到结果。通过使用 --headed 标记,可以以 headed 模式运行测试。

5.1. 运行测试

因为 Playwright 运行在 Python 中,所以可以使用 Debugger 调试它。Playwright 自带 Playwright Inspector,它允许你逐步通过 Playwright API 调用,查看它们的调试日志,以及探索选择器(selectors)。

108614092-8c478a80-73ac-11eb-9597-67dfce110e00.png

查看调试指南(debugging guide)了解关于 Playwright Inspector 以及使用浏览器开发者工具(Browser Developer tools)进行调试的更多信息。


6. 测试生成器

Playwright 具有开箱即用的生成测试的能力,这是快速开始测试的好方法。它会打开两个窗口,一个是浏览器窗口,通过它你可以与希望测试的网站进行交互,另一个是 Playwright Inspector 窗口,通过它你可以录制测试、拷贝测试、清除测试以及改变测试的语言。

你将学习:

6.1. 运行 Codegen

运行 codegen,然后在浏览器中执行操作。Playwright 将为用户的交互生成代码。Codegen 尝试生成弹性的基于文本的选择器。

181852815-971c10da-0b55-4e54-8a73-77e1e825193c.png

当你完成与页面的交互时,按下 record 按钮停止录制,使用 copy 按钮把生成的代码拷贝到编辑器。

183905981-003c4173-0d5e-4960-8190-50e6ca71b2c3.png

使用 clear 按钮清除代码,重新开始录制。完成时,关闭 Playwright Inspector 窗口,或停止终端命令。

如欲了解有关生成测试的更多信息,请查看 Codegen 的详细指南。


7. 追踪查看器(Trace Viewer)

Playwright 追踪查看器是一个 GUI 工具,它使你可以探查测试中记录的 Playwright 追踪,可以在测试的每个操作中来回移动,可视化地查看每个操作期间正在发生什么。

你将学习:

7.1. 记录追踪

像下面一样使用 browser_context.tracing API 记录追踪:

这将记录追踪,把它导出到名称为 trace.zip 的文件中。

7.2. 打开追踪

可以使用 Playwright CLI 打开保存的追踪。

7.3. 查看追踪

通过单击每个操作或使用时间轴悬停,查看测试的追踪,以及查看操作前后的页面状态。在测试的每个步骤期间查看日志、源和网络。追踪查看器创建 DOM 快照,因此你可以与它进行交互,打开开发者工具(devtools)等。

189136442-4fc6d7a3-6f0c-4a5f-9d36-2650018b018a.png

如欲了解更多信息,请查看 Trace Viewer 的详细指南。


8. Pytest 插件参考

Playwright 提供 Pytest 插件,来编写端到端的测试。如果想开始使用它,请参考 getting started guide

8.1. 用法

使用 Pytest CLI 运行测试:

如果你想自动地添加 CLI 参数,而不是指定它们,请使用 pytest.ini 文件。

8.2. CLI 参数

8.3. Fixture

该插件为 pytest 配置 Playwright 特定的 fixture(fixtures for pytest)。为使用这些 fixture,使用 fixture 名称作为测试函数的参数。

函数作用域:这些 fixture 在测试函数请求时创建,在测试结束时销毁。

会话作用域:这些 fixture 在测试函数请求时创建,在测试结束时销毁。

自定义 fixture 选项:对于 browsercontext fixture,使用下面的 fixture 来定义自定义启动选项。

8.4. 并行:同时运行多个测试

如果测试运行在有多个 CPU 的机器上,可以通过使用 pytest-xdist 同时运行多个测试,加快测试套件的整体执行时间。

根据硬件和测试的特性,可以将 numprocesses 设置为 2 到机器上 CPU 数量之间的任意值。如果设置得过高,可能产生非预期行为。

有关 pytest 选项的常用信息,请参考 Running Tests

8.5. 示例

配置 Mypy 类型以自动补全

配置慢动作

使用 --slowmo 参数以慢动作运行测试。

通过浏览器跳过测试

在特定的浏览器上运行测试

使用自定义的浏览器通道运行

配置 base-url

使用 base-url 参数启动 Pytest。pytest-base-url 插件允许通过配置、CLI 参数或像 fixture 一样设置 base url。

忽略 HTTPS 错误

使用自定义窗口大小

设备仿真

或通过命令行 --device="iPhone 11 Pro"

持久化上下文

从持久化上下文创建测试内部的所有页面。

unittest.TestCase 一起使用

参考下面的示例,了解如何与 unittest.TestCase 一起使用。这有一个限制,仅能指定一个浏览器,并且在指定多个浏览器时,不会生成多个浏览器的矩阵。

8.6. 调试

8.6.1 使用 pdb

在代码中使用 breakpoint() 语句停止执行,获取 pdb REPL。

8.7. 部署到 CI

请查看 guides for CI providers 获取关于将测试部署到 CI/CD 的信息。


9. 认证

Playwright 可用于需要认证的自动化场景。

使用 Playwright 编写的测试在被称为浏览器上下文(browser contexts)的、独立的、干净的环境中执行。这种隔离模型可以提升复现性,防止级联测试失败。新浏览器上下文可以加载现有的认证状态。这可以消除在每个上下文中登录的需求,加快测试执行的速度。

注意:本指南覆盖 cookie/token-based 认证(通过 app UI 登陆)。对于 HTTP 认证(HTTP authentication),请使用 browser.new_context(**kwargs)

9.1. 自动化登录

Playwright API 可以与登陆表单自动化交互(automate interaction)。

下面的示例自动化登陆到 Github。执行这些步骤后,浏览器上下文将被认证。

为每次测试重做登录将减慢测试的执行速度。为缓解这种情况,应该重用现有的认证状态。

9.2. 重用签入状态

Playwright 提供在测试中重用签入(signed-in)状态的方式。通过该方式,可以只登陆一次,然后跳过所有测试的登陆步骤。

Web 应用使用基于 Cookie 或基于 Token 的认证,认证状态被当作 Cookie 存储,或被存储在 Local Storage 中。Playwright 提供 browserContext.storageState(options) 方法,可使用它从已认证上下文中获取存储状态,然后使用预填充状态创建新上下文。

Cookie 和 Local Storage 状态可以跨不同的浏览器使用。它们依赖应用程序的认证模型:有些应用程序可能同时需要 Cookie 和 Local Storage。

下面的代码片段从已认证上下文中获取状态,然后使用该状态创建新上下文。

9.3. Session Storage

Session Storage 很少用于存储与登陆状态相关的信息。Session Storage 特定于特定的域,页面加载时它不会持久化。Playwright 未提供持久化 Session Storage 的 API,但下面的片段可用于保存/加载 Session Storage。

9.4. 多因子认证

使用多因子认证(MFA)的账户无法完全自动化,需要人工干预。持久化认证可用于部分自动化 MFA 场景。

9.4.1 持久化认证

注意:持久化认证不适用于 CI 环境,因为它依赖磁盘位置。用户数据目录特定于浏览器类型,不能跨浏览器类型共享。

用户数据目录可以与 browser_type.launch_persistent_context(user_data_dir, **kwargs) API 一起使用。

生命周期

  1. 在磁盘上创建用户数据目录
  2. 使用用户数据目录启动持久化上下文,然后登陆 MFA 账户
  3. 重用用户数据目录来运行自动化场景

10. 事件

Playwright 允许监听发生在 Web 页面上的多种类型的事件,比如网络请求、子页面的创建、专用 Worker 等。可通过多种方式订阅这些事件,比如等待事件或添加/移除事件监听者。

10.1. 等待事件

大多数时间,脚本需要等待特定的事件发生。下面是一些典型的事件等待模式。

使用 page.expect_request(url_or_predicate, **kwargs) 等待拥有指定 URL 的请求:

等待弹出窗口:

10.2. 添加/移除事件监听者

有时,事件发生在随机时间,而不是等待它们,它们需要被处理。Playwright 支持订阅/取消订阅事件的传统语言机制:

10.3. 添加一次性监听者

如果特定事件需要被处理一次,那么可以使用便捷的 API:


11. API 测试

Playwright 可用于访问应用程序的 REST API。

有时,你可能想通过 Python 直接向服务端发送请求,而非加载页面,在其中运行 js 代码。此时,Playwright 可以派上用场的一些示例如下:

这些都可以通过 APIRequestContext 方法实现。

下面的示例依赖 pytest-playwright 包,它向 Pytest test-runner 添加 Playwright fixture。

11.1. 编写 API 测试

APIRequestContext 可以通过网络发送各种 HTTP(S) 请求。

下面的示例展示如何使用 Playwright 通过 GitHub API 测试 issue 创建。测试套件做如下事情:

11.1.1. 配置

Github API 需要认证,因此我们将为所有测试配置一次 token。同时,我们也将设置 baseURL 以简化测试。

11.1.2. 编写测试

现在我们已初始化请求对象,我们可以添加一些在仓库中创建新 issue 的测试。

11.1.3. 准备(setup)和销毁(teardown)

这些测试假定仓库存在。你可能想在运行测试之前创建新仓库,之后删除它。为此使用 session fixtureyield 之前的部分在所有测试之前执行,之后的部分在所有测试之后执行。

11.1.4. 完成样例测试

这是 API 测试的完整样例:

11.2. 通过 API 调用准备服务端状态

下面的测试通过 API 创建新 issue,然后导航到项目中所有 issue 的列表,检查它是否出现在列表的顶部。使用 LocatorAssertions 执行该检查。

11.3. 在运行用户操作后,检查服务器状态

下面的测试通过浏览器中的用户接口创建新 issue,然后通过 API 检查它是否被创建。

11.4. 重用认证状态

Web 应用程序使用基于 Cookie 或基于 Token 的认证,认证状态被存储为 Cookies。Playwright 提供 api_request_context.storage_state(**kwargs) 方法,它可用于从已认证上下文中获取存储状态,然后使用该状态创建新上下文。

BrowserContextAPIRequestContext 之间可交换存储状态。你可以通过 API 调用登录,然后使用已有的 Cookie 创建新上下文。下面的代码片段从已认证 APIRequestContext 获取状态,然后使用该状态创建新浏览器上下文(BrowserContext)。