这份持续更新的文档旨在规定在 Gutenberg 项目中使用 Playwright 编写端到端(E2E)测试的规范说明和最佳实践。
运行测试
# 运行所有可用的测试。
npm run test:e2e
# 以有头模式运行。
npm run test:e2e -- --headed
# 使用特定的浏览器(`chromium`、`firefox` 或 `webkit`)运行测试。
npm run test:e2e -- --project=webkit --project=firefox
# 运行单个测试文件。
npm run test:e2e -- <path_to_test_file> # 例如:npm run test:e2e -- site-editor/title.spec.js
# 调试。
npm run test:e2e -- --debug
如果你在 Linux 上进行开发,目前需要以有头模式测试 Webkit 浏览器。如果你不想或无法在 GUI 下运行(例如没有图形界面),请在命令前加上 xvfb-run,以便在虚拟环境中运行。
# 运行所有可用的测试。
xvfb-run npm run test:e2e
# 仅运行 webkit 测试。
xvfb-run -- npm run test:e2e -- --project=webkit
如果你已经在 VS Code 中进行编辑,你可能会发现 Playwright 扩展对于运行、编写和调试测试很有帮助。
最佳实践
请阅读 Playwright 的最佳实践指南。
禁用 $,改用 locator
事实上,任何返回 ElementHandle 的 API 都是不推荐使用的。这包括 $、$$、$eval、$$eval 等。Locator 是一个好得多的 API,并且可以与 playwright 的断言配合使用。由于 locator 是惰性的且不返回 promise,它也能与页面对象模型(Page Object Model)很好地配合使用。
使用无障碍选择器
尽可能使用 getByRole 来构建查询。它使我们能够编写无障碍查询,而无需依赖内部实现。
// 选择一个包含无障碍名称 "Hello World" 的按钮(不区分大小写)。
page.getByRole( 'button', { name: 'Hello World' } );
它还可以链式调用来执行复杂查询:
// 选择 "Block Library" 区域下名为 "Buttons" 的选项。
page.getByRole( 'region', { name: 'Block Library' } )
.getByRole( 'option', { name: 'Buttons' } )
有关如何使用它们的更多信息,请参阅官方文档。
选择器默认为严格模式
为了鼓励在查询元素时采用更好的实践,选择器默认是严格的,这意味着如果查询返回多个元素,将会抛出错误。
内联简单的实用工具辅助函数
大多数实用函数都非常简单,可以直接内联到测试中。借助无障碍选择器,现在编写简单的工具函数更容易了。对于仅在特定页面上使用的工具函数,请改用页面对象模型(Page Object Model)。否则,只有当操作足够复杂且重复时,才创建工具函数。
优先使用页面对象模型而非工具函数
如上所述,页面对象模型是在特定页面上创建可重用实用函数的首选方式。
使用 POM 的理由是将工具函数归组到命名空间之下,从而更容易发现和使用。事实上,e2e-test-utils-playwright 包中的 PageUtils 也是一个 POM,它避免了使用全局变量的需要,并且工具函数可以通过 this 相互引用。
对清除或设置状态的操作进行 REST 化
在测试之前或之后手动设置状态很慢,尤其是当这些操作在多个测试之间重复多次时。建议通过 API 调用来设置它们。请改用 requestUtils.rest 和 requestUtils.batchRest 来调用 REST API(如有需要,可将它们添加到 requestUtils 中)。我们仍然应该为手动设置它们添加一个测试,但该测试只需进行一次。
避免全局变量
在之前的 E2E 设置中,page 和 browser 是全局变量,这使得处理多个页面或并行测试变得更加困难。
@playwright/test 使用 fixtures 将 page、browser 和其他参数注入到测试中。
进行显式断言
我们可以在一个测试中根据需要插入任意数量的断言。尽可能进行显式断言会更好。例如,如果我们想在点击某个按钮之前断言该按钮存在,可以在执行 locator.click() 之前执行 expect( locator ).toBeVisible()。这使测试的流程更好、更易读
常见陷阱
过度使用快照
跨浏览器测试
默认情况下,测试仅在 chromium 中运行。你可以为测试添加标签,使其在不同的浏览器中运行。在测试标题的任意位置使用 @browser,即可让测试在该浏览器中运行。测试默认始终会在 chromium 中运行,附加 -chromium 可以禁用 chromium 中的测试。可用的浏览器有 chromium、firefox 和 webkit。
test( 'I will run in @firefox and @webkit (and chromium by default)', async ( { page } ) => {
// ...
} );
test( 'I will only run in @firefox but not -chromium', async ( { page } ) => {
// ...
} );
test.describe( 'Grouping tests (@webkit, -chromium)', () => {
test( 'I will only run in webkit', async ( { page } ) => {
// ...
} );
} );