快照测试
概述
通过 Playwright 快照测试,您可以根据预定义的快照模板断言页面的可访问性树。
await page.GotoAsync("https://playwright.net.cn/");
await Expect(page.Locator("banner")).ToMatchAriaSnapshotAsync(@"
- banner:
- heading ""Playwright enables reliable end-to-end testing for modern web apps."" [level=1]
- link ""Get started""
- link ""Star microsoft/playwright on GitHub""
- link /[\\d]+k\\+ stargazers on GitHub/
");
断言测试 vs 快照测试
快照测试和断言测试在测试自动化中服务于不同的目的
断言测试
断言测试是一种有针对性的方法,您可以在其中断言关于元素或组件的特定值或条件。例如,使用 Playwright,Expect(Locator).ToHaveTextAsync() 验证元素是否包含预期的文本,而 Expect(Locator).ToHaveValueAsync() 确认输入字段是否具有预期的值。断言测试是具体的,通常检查元素或属性的当前状态是否与预期的、预定义的状态相符。它们适用于可预测的、单值检查,但在测试更广泛的结构或变体时范围有限。
优势
- 清晰性:测试的意图是明确且易于理解的。
- 特异性:测试专注于功能的特定方面,使其对于不相关的更改更具鲁棒性。
- 调试:失败提供有针对性的反馈,直接指向有问题的方面。
缺点
- 对于复杂输出而言冗长:为复杂的数据结构或大型输出编写断言可能很繁琐且容易出错。
- 维护开销:随着代码的演变,手动更新断言可能非常耗时。
快照测试
快照测试捕获元素、组件或数据在给定时刻的整个状态的“快照”或表示,然后保存以供将来比较。当重新运行测试时,当前状态将与快照进行比较,如果存在差异,则测试失败。这种方法对于复杂或动态的结构尤其有用,在这些结构中,手动断言每个细节将非常耗时。快照测试比断言测试更广泛、更全面,使您可以跟踪随着时间推移更复杂的更改。
优势
- 简化复杂输出:例如,使用传统的断言测试 UI 组件的渲染输出可能很乏味。快照捕获整个输出以方便比较。
- 快速反馈循环:开发人员可以轻松发现输出中意外的更改。
- 鼓励一致性:帮助在代码演变时保持一致的输出。
缺点
- 过度依赖:可能会很想在没有完全理解的情况下接受对快照的更改,从而可能隐藏错误。
- 粒度:当出现差异时,大型快照可能难以解释,尤其是在细微更改影响大部分输出的情况下。
- 适用性:不适用于输出频繁或不可预测地变化的高度动态内容。
何时使用
- 快照测试非常适合
- 整个页面和组件的 UI 测试。
- 复杂 UI 组件的广泛结构检查。
- 很少更改结构的输出的回归测试。
- 断言测试非常适合
- 核心逻辑验证。
- 计算值测试。
- 需要精确条件的细粒度测试。
通过结合快照测试进行广泛的结构检查和断言测试进行特定功能,您可以实现完善的测试策略。
Aria 快照
在 Playwright 中,aria 快照提供了页面可访问性树的 YAML 表示。这些快照可以存储并在以后进行比较,以验证页面结构是否保持一致或满足定义的期望。
YAML 格式描述了页面上可访问元素的层次结构,详细说明了 角色、属性、值 和 文本内容。该结构遵循类似树的语法,其中每个节点代表一个可访问的元素,而缩进表示嵌套的元素。
树中的每个可访问元素都表示为一个 YAML 节点
- role "name" [attribute=value]
- role:指定元素的 ARIA 或 HTML 角色(例如,
heading
、list
、listitem
、button
)。 - "name":元素的可访问名称。带引号的字符串表示确切的值,
/patterns/
用于正则表达式。 - [attribute=value]:属性和值,在方括号中,表示特定的 ARIA 属性,例如
checked
、disabled
、expanded
、level
、pressed
或selected
。
这些值源自 ARIA 属性或根据 HTML 语义计算得出。要检查页面的可访问性树结构,请使用 Chrome DevTools Accessibility Pane。
快照匹配
Playwright 中的 Expect(Locator).ToMatchAriaSnapshotAsync() 断言方法将定位器范围的可访问结构与预定义的 aria 快照模板进行比较,从而帮助验证页面的状态是否符合测试要求。
对于以下 DOM
<h1>title</h1>
您可以使用以下快照模板进行匹配
await Expect(page.Locator("body")).ToMatchAriaSnapshotAsync(@"
- heading ""title""
");
匹配时,快照模板将与页面的当前可访问性树进行比较
- 如果树结构与模板匹配,则测试通过;否则,测试失败,表明预期状态和实际可访问性状态之间存在不匹配。
- 比较区分大小写并折叠空格,因此缩进和换行符将被忽略。
- 比较对顺序敏感,这意味着快照模板中元素的顺序必须与页面可访问性树中的顺序匹配。
部分匹配
您可以通过省略属性或可访问名称对节点执行部分匹配,从而无需精确匹配即可验证可访问性树的特定部分。这种灵活性对于动态或不相关的属性很有帮助。
<button>Submit</button>
aria 快照
- button
在此示例中,匹配了按钮角色,但未指定可访问名称(“Submit”),从而允许测试通过,而与按钮的标签无关。
对于具有 ARIA 属性(如 checked
或 disabled
)的元素,省略这些属性允许部分匹配,仅关注角色和层次结构。
<input type="checkbox" checked>
用于部分匹配的 aria 快照
- checkbox
在此部分匹配中,checked
属性被忽略,因此无论复选框状态如何,测试都将通过。
同样,您可以通过省略特定的列表项或嵌套元素来部分匹配列表或组中的子项。
<ul>
<li>Feature A</li>
<li>Feature B</li>
<li>Feature C</li>
</ul>
用于部分匹配的 aria 快照
- list
- listitem: Feature B
部分匹配使您可以创建灵活的快照测试,以验证基本的页面结构,而无需强制执行特定的内容或属性。
使用正则表达式匹配
正则表达式允许对具有动态或可变文本的元素进行灵活匹配。可访问名称和文本可以支持正则表达式模式。
<h1>Issues 12</h1>
带有正则表达式的 aria 快照
- heading /Issues \d+/
生成快照
在 Playwright 中创建 aria 快照有助于确保和维护应用程序的结构。您可以根据您的测试设置和工作流程以各种方式生成快照。
1. 使用 Playwright 代码生成器生成快照
如果您正在使用 Playwright 的 代码生成器,则通过其交互式界面可以简化 aria 快照的生成
- “断言快照”操作:在代码生成器中,您可以使用“断言快照”操作自动为选定的元素创建快照断言。这是捕获 aria 快照作为记录的测试流程的一部分的快速方法。
- “Aria 快照”选项卡:“Aria 快照”选项卡在代码生成器界面中以可视化方式表示选定定位器的 aria 快照,使您可以探索、检查和验证元素角色、属性和可访问名称,以帮助快照创建和审查。
2. 使用 @playwright/test
和 --update-snapshots
标志更新快照
当使用 Playwright 测试运行器 (@playwright/test
) 时,您可以通过使用 --update-snapshots
标志运行测试来自动更新快照
npx playwright test --update-snapshots
此命令会重新生成断言(包括 aria 快照)的快照,从而替换过时的快照。当应用程序结构更改需要新的快照作为基线时,这非常有用。请注意,Playwright 将等待测试运行器配置中指定的最大期望超时,以确保页面在拍摄快照之前已稳定。如果测试在生成快照时达到超时,则可能需要调整 --timeout
。
用于快照生成的空模板
在断言中传递空字符串作为模板会动态生成快照
请注意,Playwright 将等待测试运行器配置中指定的最大期望超时,以确保页面在拍摄快照之前已稳定。如果测试在生成快照时达到超时,则可能需要调整 --timeout
。
快照补丁文件
更新快照时,Playwright 会创建捕获差异的补丁文件。可以审查、应用这些补丁文件并将其提交到源代码控制,从而使团队可以跟踪随时间推移的结构更改并确保更新与应用程序要求一致。
3. 使用 Locator.ariaSnapshot
方法
Locator.AriaSnapshotAsync() 方法允许您以编程方式创建定位器范围内可访问元素的 YAML 表示,这对于在测试执行期间动态生成快照特别有用。
示例:
var snapshot = await page.Locator("body").AriaSnapshotAsync();
Console.WriteLine(snapshot);
此命令以 YAML 格式输出指定定位器范围内的 aria 快照,您可以根据需要对其进行验证或存储。
可访问性树示例
带有级别属性的标题
标题可以包含一个 level
属性,指示其标题级别。
<h1>Title</h1>
<h2>Subtitle</h2>
aria 快照
- heading "Title" [level=1]
- heading "Subtitle" [level=2]
文本节点
独立的或描述性的文本元素显示为文本节点。
<div>Sample accessible name</div>
aria 快照
- text: Sample accessible name
内联多行文本
多行文本(例如段落)在 aria 快照中被规范化。
<p>Line 1<br>Line 2</p>
aria 快照
- paragraph: Line 1 Line 2
链接
链接显示其文本或来自伪元素的组合内容。
<a href="#more-info">Read more about Accessibility</a>
aria 快照
- link "Read more about Accessibility"
文本框
类型为 text
的输入元素显示其 value
属性内容。
<input type="text" value="Enter your name">
aria 快照
- textbox: Enter your name
带有项目的列表
有序列表和无序列表都包含其列表项。
<ul aria-label="Main Features">
<li>Feature 1</li>
<li>Feature 2</li>
</ul>
aria 快照
- list "Main Features":
- listitem: Feature 1
- listitem: Feature 2
分组元素
组捕获嵌套元素,例如带有摘要内容的 <details>
元素。
<details>
<summary>Summary</summary>
<p>Detail content here</p>
</details>
aria 快照
- group: Summary
属性和状态
常用的 ARIA 属性,如 checked
、disabled
、expanded
、level
、pressed
和 selected
,表示控件状态。
带有 checked
属性的复选框
<input type="checkbox" checked>
aria 快照
- checkbox [checked]
带有 pressed
属性的按钮
<button aria-pressed="true">Toggle</button>
aria 快照
- button "Toggle" [pressed=true]