提问人:Captain flapjack 提问时间:11/16/2023 最后编辑:YaroslavmCaptain flapjack 更新时间:11/19/2023 访问量:54
如何使用 Playwright 为 DOM 中的元素定义最有效的定位器
How to define the most efficient locator for element in DOM using Playwright
问:
我正在为具有多个区域设置的网站添加 Playwright 测试。页面内容主要通过CMS内容呈现(我使用的是Contentful)。
与硬编码文本一起使用,例如似乎很脆弱,尤其是在多个区域设置中。locators
await page.getByLabel('Blog Article Foo').click();
我是否应该避免使用任何基于文本的定位器,而只使用?await page.getByRole('heading').click();
这似乎不是“剧作家”的测试方式,因为我不是在测试用户看到/与之交互的内容,但是我能看到的唯一选择是为每个区域设置编写大量非常不稳定的测试并不断更新它们。
我错过了什么吗?
答:
自动化主要是与用户看到的无关。它是关于用户流的,可以由符合产品逻辑的用户从头开始完成,按原样使用用户资源(浏览器等)。
渲染的组件通常通过视觉(屏幕截图)测试进行检查,其部分应该是所有覆盖率(测试金字塔)的最低部分,其中 e2e 可以按功能和视觉进行拆分。
在大多数情况下,您关心的是存在/呈现/可见/可点击/具有某些样式和属性的元素,但不关心其文本本身。文本通常由内容键定义,因此在大多数情况下无需对其进行测试。它可以按单位进行测试,该元素具有键,并且该键具有值,但这不是 e2e 测试的目的。
- 如果您有权访问源代码并可以更改它,则最佳做法是为元素分配唯一的定位符并在 e2e 中使用它。
例如
[data-testid=heading]
或page.getByDataTestId('heading')
[data-hook=heading]
[data-aid=heading]
如果您无法自己分配属性并查看此属性 - 最好使用它们,它们肯定用于自动化,并且它们很可能不会更改。
然后你应该依赖元素,但在这种情况下,你应该考虑,该 id 是唯一的(根据最佳实践,它应该是唯一的,但某些资源会忽略此模式)并且不是自动生成的。
id
依靠表示其类型或使用目的的元素属性,
input[type=search]
[role=heading]
依靠看似唯一的属性类或属性和类之间的组合,
.headingContainer
div.headingContainer
依赖自定义标签,如 、 等。但请注意,它们可以在不同的本地化中更改。(有时不是,有时是)
name
title
依靠唯一标签(例如,youtube 有许多唯一标签),如 、 等。
ytb-video-container
ytb-video-player
依靠 href 或 src 部分 , .这不是最佳实践,但如果不更改 src 部分,则可以使用。
img[src*=imgur]
[href*=imgur]
仅当您没有任何其他选项时,才能在构建定位器时使用文本。文本是非常敏感的区域,可以很容易地通过产品逻辑进行更改,并且它因网站本地化而异。 例如,如果您目前只有英语,但将来您希望将该网站翻译成葡萄牙语,并且您应该对其进行测试,则应避免使用任何基于文本的定位器。
在构建定位器时,尽量让它变得更容易,如果可能的话,使用一级,如果不可能,则使用一级 - 依赖组件容器并从中获取子元素。
例:
const posts = await page.locator('#blogPostContainer').all();
for(const post of posts) {
await post.getByRole('heading').click();
// do something
}
评论