快照测试
概述
借助 Playwright 的快照测试,你可以根据预定义的快照模板断言页面的可访问性树。
await page.GotoAsync("https://playwright.dev/");
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/
");
断言测试与快照测试
在测试自动化中,快照测试和断言测试有着不同的用途:
断言测试
断言测试是一种有针对性的方法,你可以在其中断言有关元素或组件的特定值或条件。例如,使用 Playwright 时,Expect(Locator).ToHaveTextAsync() 会验证某个元素是否包含预期文本,而 Expect(Locator).ToHaveValueAsync() 会确认某个输入字段是否具有预期值。断言测试具有特定性,通常会将元素或属性的当前状态与预期的预定义状态进行比较。它们适用于可预测的单值检查,但在测试更广泛的结构或变化时,其作用范围有限。
优点
- 清晰性:测试意图明确,易于理解。
- 针对性:测试专注于功能的特定方面,使其对不相关的更改更具鲁棒性。
- 调试:失败时会提供有针对性的反馈,直接指出有问题的方面。
缺点
- 复杂输出时冗长:为复杂数据结构或大量输出编写断言可能既繁琐又容易出错。
- 维护成本:随着代码的演变,手动更新断言可能很耗时。
快照测试
快照测试会捕获元素、组件或数据在特定时刻的整个状态的 “快照” 或表示形式,然后将其保存以供将来比较。重新运行测试时,会将当前状态与快照进行比较,如果存在差异,则测试失败。这种方法对于复杂或动态结构特别有用,因为手动断言每个细节会非常耗时。快照测试比断言测试更广泛、更全面,使您能够随时间跟踪更复杂的变化。
优点
- 简化复杂输出:例如,使用传统断言测试 UI 组件的渲染输出可能很乏味。快照会捕获整个输出,便于比较。
- 快速反馈循环:开发人员可以轻松发现输出中意外的变化。
- 促进一致性:有助于在代码演变时保持一致的输出。
缺点
- 过度依赖:开发人员可能会在不完全理解的情况下接受对快照的更改,这可能会隐藏 bug。
- 粒度问题:当出现差异时,大型快照可能难以解释,特别是如果微小的更改影响了输出的大部分内容。
- 适用性问题:对于高度动态的内容(输出频繁或不可预测地变化)不太适用。
何时使用
- 快照测试 适用于:
- 整页和组件的 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 可访问性选项卡。
快照匹配
Playwright 中的 Expect(Locator).ToMatchAriaSnapshotAsync() 断言方法会将定位器作用域的可访问结构与预定义的 ARIA 快照模板进行比较,有助于根据测试要求验证页面状态。
对于以下 DOM:
<h1>title</h1>
你可以使用以下快照模板进行匹配:
await Expect(page.Locator("body")).ToMatchAriaSnapshotAsync(@"
- heading ""title""
");
匹配时,会将快照模板与页面当前的可访问性树进行比较:
- 如果树结构与模板匹配,则测试通过;否则,测试失败,表明预期的可访问性状态与实际状态不匹配。
- 比较区分大小写并会折叠空白字符,因此缩进和换行符将被忽略。
- 比较对顺序敏感,这意味着快照模板中元素的顺序必须与页面可访问性树中的顺序匹配。
部分匹配
你可以通过省略属性或可访问名称来对节点执行部分匹配,这样无需精确匹配即可验证可访问性树的特定部分。这种灵活性对于动态或无关紧要的属性很有帮助。
<button>Submit</button>
可访问性树状图快照
- button
在此示例中,匹配了按钮角色,但未指定可访问名称(“Submit”),因此无论按钮标签是什么,测试都将通过。
对于具有 checked
或 disabled
等 ARIA 属性的元素,省略这些属性可实现部分匹配,仅关注角色和层次结构。
<input type="checkbox" checked>
部分匹配的可访问性树状图快照
- checkbox
在此部分匹配中,checked
属性被忽略,因此无论复选框状态如何,测试都将通过。
同样,你可以通过省略特定列表项或嵌套元素,对列表或组中的子元素进行部分匹配。
<ul>
<li>Feature A</li>
<li>Feature B</li>
<li>Feature C</li>
</ul>
部分匹配的可访问性树状图快照
- list
- listitem: Feature B
部分匹配使你能够创建灵活的快照测试,验证基本页面结构,而无需强制特定内容或属性。
严格匹配
默认情况下,包含部分子元素的模板将被匹配:
<ul>
<li>功能 A</li>
<li>功能 B</li>
<li>功能 C</li>
</ul>
部分匹配的 ARIA 快照
- list
- listitem: 功能 B
/children
属性可用于控制如何匹配子元素:
contain
(默认值):如果所有指定的子元素按顺序存在,则匹配equal
:如果子元素与指定列表按顺序完全匹配,则匹配deep-equal
:如果子元素与指定列表按顺序完全匹配,包括嵌套子元素,则匹配
<ul>
<li>功能 A</li>
<li>功能 B</li>
<li>功能 C</li>
</ul>
由于模板中没有功能 C,ARIA 快照将失败
- list
- /children: equal
- listitem: 功能 A
- listitem: 功能 B
使用正则表达式匹配
正则表达式允许灵活匹配具有动态或可变文本的元素。可访问名称和文本可以支持正则表达式模式。
<h1>问题 12</h1>
带正则表达式的 ARIA 快照
- heading /问题 \d+/
生成快照
在 Playwright 中创建 ARIA 快照有助于确保和维护应用程序的结构。您可以根据测试设置和工作流程以各种方式生成快照。
使用 Playwright 代码生成器生成快照
如果您正在使用 Playwright 的代码生成器,通过其交互式界面可以简化生成可访问性树(aria)快照的过程:
- “断言快照”操作:在代码生成器中,您可以使用“断言快照”操作,为选定的元素自动创建快照断言。这是一种快速捕获可访问性树(aria)快照的方法,可作为您录制的测试流程的一部分。
- “可访问性树(aria)快照”选项卡:代码生成器界面中的“可访问性树(aria)快照”选项卡以可视化方式展示选定定位器的可访问性树(aria)快照,使您能够探索、检查和验证元素角色、属性及可访问名称,以辅助快照的创建和审查。
使用 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)快照
- 标题 "Title" [level=1]
- 标题 "Subtitle" [level=2]
文本节点
独立或描述性文本元素显示为文本节点。
<div>Sample accessible name</div>
可访问性树(aria)快照
- 文本: Sample accessible name
内联多行文本
多行文本(如段落)在可访问性树(aria)快照中会被规范化。
<p>Line 1<br>Line 2</p>
可访问性树(aria)快照
- 段落: Line 1 Line 2
链接
链接会显示其文本或来自伪元素的组合内容。
<a href="#more-info">详细了解可访问性</a>
aria 快照
- 链接 "详细了解可访问性"
文本框
类型为 text
的输入元素会显示其 value
属性内容。
<input type="text" value="输入您的姓名">
aria 快照
- 文本框: 输入您的姓名
带项目的列表
有序列表和无序列表包含其列表项。
<ul aria-label="主要功能">
<li>功能 1</li>
<li>功能 2</li>
</ul>
aria 快照
- 列表 "主要功能":
- 列表项: 功能 1
- 列表项: 功能 2
分组元素
分组会捕获嵌套元素,例如带有摘要内容的 <details>
元素。
<details>
<summary>摘要</summary>
<p>此处为详细内容</p>
</details>
aria 快照
- 组: 摘要
属性和状态
常用的 ARIA 属性,如 checked
、disabled
、expanded
、level
、pressed
和 selected
,表示控件状态。
带有 checked
属性的复选框
<input type="checkbox" checked>
aria 快照
- 复选框 [已选中]
带有 pressed
属性的按钮
<button aria-pressed="true">切换</button>
aria 快照
- 按钮 "切换" [已按下=true]