最佳实践
测试哲学
测试用户可见的行为
自动化测试应该验证应用程序代码是否对最终用户有效,而避免依赖实现细节(例如,用户通常不会使用、看到或知道的内容,比如函数的名称、某个元素是否是数组,或者元素的 CSS 类)。最终用户将看到或与页面上的内容进行交互,因此您的测试应主要测试和与用户看到的渲染输出进行交互。
使测试尽可能隔离
每个测试应完全独立,不应依赖于其他测试,并应使用自己的本地存储、会话存储、数据、Cookie 等。【测试隔离】提高了可重复性,简化了调试,并防止级联的测试失败。
为了避免重复测试中的某个部分,您可以使用 【before 和 after 钩子】。在您的测试文件中添加 before 钩子,在每个测试之前执行某些操作,例如跳转到特定 URL 或登录到应用程序的某个部分。这可以保持测试的隔离,因为没有测试依赖于其他测试。然而,如果测试足够简单,尤其是有助于使测试更清晰、易于阅读和维护,稍微重复一些也是可以接受的。
import { test } from '@playwright/test';
test.beforeEach(async ({ page }) => {
// Runs before each test and signs in each page.
await page.goto('https://github.com/login');
await page.getByLabel('Username or email address').fill('username');
await page.getByLabel('Password').fill('password');
await page.getByRole('button', { name: 'Sign in' }).click();
});
test('first', async ({ page }) => {
// page is signed in.
});
test('second', async ({ page }) => {
// page is signed in.
});
您还可以使用设置项目(【setup project】)在测试中复用已登录的状态。这样,您只需要登录一次,然后跳过所有测试中的登录步骤。
避免测试第三方依赖
只测试您可以控制的部分。不要尝试测试指向外部站点或您无法控制的第三方服务器的链接。这样不仅会浪费时间并减慢测试速度,而且您无法控制链接到的页面的内容,或者是否存在 Cookie 横幅、遮罩层页面或其他可能导致测试失败的因素。
相反,使用 【Playwright 的网络 API】 并保证所需的响应。
await page.route('**/api/fetch_data_third_party_dependency', route => route.fulfill({
status: 200,
body: testData,
}));
await page.goto('https://example.com');
最佳实践
使用定位器
为了编写端到端测试,我们首先需要在网页中找到元素。可以使用 Playwright 内置的【定位器】来实现。定位器具有自动等待和重试功能。自动等待意味着 Playwright 会在执行操作之前,进行一系列的操作性检查,例如确保元素可见且已启用。为了提高测试的韧性,我们建议优先选择用户可见的属性和显式的契约。
// 👍
page.getByRole('button', { name: 'submit' });
生成定位器
Playwright 提供了一个【测试生成器】,可以为您生成测试并挑选定位器。它会查看您的页面,并选择最佳的定位器,优先选择角色、文本和测试 ID 定位器。如果生成器找到多个匹配的元素,它会改进定位器,使其更加稳健,确保唯一地标识目标元素,这样您就不必担心定位器导致的测试失败。
使用代码生成器生成定位器
要选择定位器,运行 codegen
命令并跟上您想要挑选定位器的 URL。
npx playwright codegen playwright.dev
yarn playwright codegen playwright.dev
pnpm exec playwright codegen playwright.dev
这将打开一个新的浏览器窗口以及 Playwright 检查器。首先点击 "Record" 按钮停止录制。默认情况下,运行 codegen
命令时会开始新的录制。停止录制后,您将看到 "Pick Locator" 按钮。
然后,您可以将鼠标悬停在页面中的任何元素上,查看定位器并将其添加到 Playwright 检查器中。您可以将定位器复制并粘贴到测试文件中,或继续在 Playwright 检查器中编辑它,修改文本并查看浏览器窗口中的效果。

使用 Web-first 断言
断言是一种验证预期结果和实际结果是否匹配的方式。通过使用 【Web-first 断言】,Playwright 会等待直到预期条件满足。例如,测试一个警告消息时,测试会点击一个按钮使消息出现,并检查该警告消息是否存在。如果警告消息需要半秒钟才能出现,断言(如 toBeVisible()
)将等待并在需要时重试。
// 👍
await expect(page.getByText('welcome')).toBeVisible();
// 👎
expect(await page.getByText('welcome').isVisible()).toBe(true);
配置调试
本地调试
对于本地调试,我们建议您在 VSCode 中实时调试测试,通过安装 VS Code 扩展。您可以通过右键单击测试旁边的行,在调试模式下运行测试,这将打开一个浏览器窗口并在设置的断点处暂停。

您可以通过在 VS Code 中点击或编辑测试中的定位器来实时调试测试,这将高亮显示浏览器窗口中的该定位器,并显示页面上找到的其他匹配定位器。

您还可以通过在运行测试时加上 --debug
标志,使用 Playwright 检查器调试您的测试。
npx playwright test --debug
yarn playwright test --debug
pnpm exec playwright test --debug
然后,您可以逐步调试测试,查看可操作性日志,实时编辑定位器,并在浏览器窗口中查看定位器高亮显示。这将显示匹配的定位器以及它们的数量。

要调试特定的测试,添加测试文件的名称和测试的行号,然后加上 --debug
标志。
在 CI 上调试
对于 CI 失败,建议使用 Playwright 的 trace viewer,而不是视频和截图。Trace viewer 会以本地渐进式 Web 应用(PWA)的形式提供完整的测试跟踪,且可以轻松分享。通过 trace viewer,你可以查看时间线、使用开发者工具检查每个操作的 DOM 快照、查看网络请求等。

在 Playwright 配置文件中可以配置 trace,并设置在 CI 上的第一次重试时运行。我们不推荐在每个测试中都启用 trace,因为这会对性能造成较大影响。不过,在本地开发时,你可以使用 --trace
标志来运行 trace。
npx playwright test --trace on
yarn playwright test --trace on
pnpm exec playwright test --trace on
一旦你运行此命令,所有测试的 trace 将被记录,并且可以直接从 HTML 报告中查看。
npx playwright show-report
yarn playwright show-report
pnpm exec playwright show-report

可以通过点击测试文件名旁边的图标,或者打开每个测试报告并向下滚动到 trace 部分来查看 trace。

使用 Playwright 工具
Playwright 提供了一系列工具来帮助你编写测试。
-
VS Code 插件:为你提供了很好的开发体验,用于编写、运行和调试测试。
-
测试生成器:可以为你生成测试并选择定位器。
-
Trace 查看器:为你的测试提供完整的追踪,作为本地的渐进式 Web 应用(PWA),并且容易共享。通过 Trace 查看器,你可以查看时间线,使用开发者工具检查每个操作的 DOM 快照,查看网络请求等。
-
UI 模式:让你在“时光旅行”体验中探索、运行和调试测试,带有观察模式。所有的测试文件都加载到测试侧边栏,你可以展开每个文件和描述块,单独运行、查看、观察和调试每个测试。
-
TypeScript 支持:Playwright 默认支持 TypeScript,提供更好的 IDE 集成。IDE 会显示你可以做的所有操作,并在你做错时进行高亮提示。你不需要 TypeScript 经验,也不需要你的代码用 TypeScript 编写,只需创建 .ts 后缀的测试文件即可。
跨浏览器测试
Playwright 让你可以轻松地在所有【浏览器】上测试你的网站,无论你处于什么平台。跨浏览器测试确保你的应用适用于所有用户。在配置文件中,你可以设置项目,指定使用的浏览器或设备。
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
保持 Playwright 依赖最新
通过保持 Playwright 版本更新,你可以在最新的浏览器版本上测试你的应用,并在最新版本发布之前捕获可能的失败。
npm install -D @playwright/test@latest
yarn add --dev @playwright/test@latest
pnpm install --save-dev @playwright/test@latest
查看【发布说明】以了解最新版本及其发布的更改。
你可以通过运行以下命令来查看你当前安装的 Playwright 版本。
在 CI 上运行测试
设置 CI/CD,并频繁运行测试。理想情况下,你应该在每次提交和拉取请求时运行测试。Playwright 提供了 GitHub Actions 工作流,测试可以在 CI 上运行,无需额外设置。Playwright 也可以在你选择的 CI 环境中进行配置。
建议在 CI 上使用 Linux 环境,因为它更便宜。开发人员可以在本地使用任何环境,但在 CI 上使用 Linux。考虑设置 Sharding(分片)来加速 CI。
对测试进行 lint 检查
我们推荐使用 TypeScript 和 ESLint 来进行测试的 lint 检查,尽早捕获错误。使用 @typescript-eslint/no-floating-promises
ESLint 规则,确保在异步调用 Playwright API 时没有遗漏的 await。在 CI 中,你可以运行 tsc --noEmit
来确保函数调用签名正确。
使用并行性和分片
Playwright 默认以并行方式运行测试。单个文件中的测试按顺序在同一工作进程中运行。如果你有许多独立的测试,可以考虑将它们并行运行。
import { test } from '@playwright/test';
test.describe.configure({ mode: 'parallel' });
test('runs in parallel 1', async ({ page }) => { /* ... */ });
test('runs in parallel 2', async ({ page }) => { /* ... */ });
Playwright 还支持对测试套件进行分片(sharding),这样它就可以在多台机器上执行。
提高生产力的小贴士
使用软断言(Soft assertions)
如果你的测试失败,Playwright 会给出错误信息,显示测试中失败的部分,你可以在 VS Code、终端、HTML 报告或 Trace 查看器中看到这些信息。你还可以使用软断言,它不会立即终止测试的执行,而是会在测试结束时编译并显示失败的断言列表。
// Make a few checks that will not stop the test when failed...
await expect.soft(page.getByTestId('status')).toHaveText('Success');
// ... and continue the test to check more things.
await page.getByRole('link', { name: 'next page' }).click();