停止编写脆弱的测试:每个 Playwright 开发者都需要的智能定位器策略
Source: Dev.to
我花了好几个小时调试一个因为一行 XPath 而失效的 flaky(不稳定)测试。
解决办法?写了一个用了 10 秒的 Playwright 定位器。
以下是我希望自己早点知道的内容。
硬核真相
如果你的测试不稳定,问题出在定位器上。
传统的 XPath 和 CSS 选择器像树一样遍历 DOM。只要开发者重新排序元素或更改结构——你的测试就会 立刻 失效。每一次,都是如此。
// 脆弱 – DOM 结构变化就会失效
page.locator('div#main > ul:nth-child(2) > li:first-child > button')
人类视觉 vs 机器人视觉
Playwright 采用完全不同的思路。它不去寻找 ID 或类名(机器人视觉),而是像真实用户一样——通过他们在屏幕上看到的内容(人类视觉)来定位元素。
金标准?page.getByRole()
它利用 可访问性树——屏幕阅读器使用的同一结构。如果屏幕阅读器能找到它,Playwright 也能测试它。并且在重构后仍然有效。
// 智能 – 能适应 DOM 变化
page.getByRole('button', { name: 'Sign up' })
定位器优先级层级
按以下顺序使用,你可以解决约 80% 的定位器问题:
- getByRole – 首先使用它。适用于按钮、标题、复选框、链接等。
- getByText / getByLabel – 退而求其次,使用可见的屏幕文字或表单标签。
- getByTestId – 让开发者添加
data-testid属性。它稳定且不会意外改变。 - CSS/XPath – 仅作最后手段。即使如此,也可以把它粘贴到 LLM 中——它会帮你转换成
getByRole定位器。
加分项:不再需要 sleep() hack
Playwright 内置的自动等待意味着每个定位器在操作前都会自动等待元素被附加、可见、稳定且可用。再也不用写任意的超时等待了。
// 你不再需要这行代码
await page.waitForTimeout(3000);
// 使用可访问性树的推荐写法
const submitButton = await page.getByRole('button', { name: 'Submit' });
await submitButton.click();
这是我的 Playwright 80/20 帕累托原则系列的第 2 部分。第 3 部分将介绍 Playwright Actions——敬请期待!
🎬 完整视频观看地址:https://www.youtube.com/watch?v=6IaCQ70cNVc