快照測試
概觀
透過 Playwright 快照測試,您可以針對預定義的快照範本,斷言頁面的可存取性樹狀結構。
await page.goto('https://playwright.dev.org.tw/');
await expect(page.getByRole('banner')).toMatchAriaSnapshot(`
- banner:
- heading /Playwright enables reliable end-to-end/ [level=1]
- link "Get started"
- link "Star microsoft/playwright on GitHub"
- link /[\\d]+k\\+ stargazers on GitHub/
`);
斷言測試 vs 快照測試
快照測試和斷言測試在測試自動化中,服務於不同的目的
斷言測試
斷言測試是一種目標明確的方法,您可以在其中斷言元素或元件的特定值或條件。例如,使用 Playwright,expect(locator).toHaveText() 驗證元素是否包含預期的文字,而 expect(locator).toHaveValue() 確認輸入欄位是否具有預期的值。斷言測試是具體的,通常會針對預期的預定義狀態,檢查元素或屬性的目前狀態。它們適用於可預測的單一值檢查,但在測試更廣泛的結構或變化時,範圍有限。
優點
- 清晰度:測試的意圖明確且易於理解。
- 明確性:測試著重於功能的特定方面,使其更能抵抗不相關的變更。
- 偵錯:失敗會提供目標明確的回饋,直接指向有問題的方面。
缺點
- 複雜輸出的冗長:為複雜的資料結構或大型輸出編寫斷言,可能會很麻煩且容易出錯。
- 維護成本:隨著程式碼的演進,手動更新斷言可能會很耗時。
快照測試
快照測試會擷取元素、元件或資料在特定時刻的整個狀態的「快照」或表示形式,然後儲存以供未來比較。當重新執行測試時,會將目前狀態與快照進行比較,如果存在差異,則測試失敗。此方法對於複雜或動態結構特別有用,在這些結構中,手動斷言每個細節會過於耗時。快照測試比斷言測試更廣泛且更全面,可讓您追蹤更複雜的長期變更。
優點
- 簡化複雜的輸出:例如,使用傳統斷言測試 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 無障礙功能面板。
快照比對
Playwright 中的 expect(locator).toMatchAriaSnapshot() 斷言方法,將定位器範圍的可存取結構,與預定義的 aria 快照範本進行比較,有助於驗證頁面的狀態是否符合測試需求。
對於以下 DOM
<h1>title</h1>
您可以使用以下快照範本進行比對
await expect(page.locator('body')).toMatchAriaSnapshot(`
- 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
部分比對可讓您建立彈性的快照測試,以驗證必要的頁面結構,而無需強制執行特定的內容或屬性。
使用正規表示式比對
正規表示式允許彈性比對具有動態或可變文字的元素。可存取名稱和文字可以支援 regex 模式。
<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
。
用於快照產生的空白範本
在斷言中傳遞空字串作為範本,會即時產生快照
await expect(locator).toMatchAriaSnapshot('');
請注意,Playwright 會等待測試執行器配置中指定的最大預期逾時時間,以確保頁面在拍攝快照之前已穩定。如果測試在產生快照時達到逾時時間,則可能需要調整 --timeout
。
快照修補程式檔案
更新快照時,Playwright 會建立擷取差異的修補程式檔案。可以檢閱、套用這些修補程式檔案,並將其提交至原始碼控制,讓團隊可以追蹤長期的結構變更,並確保更新與應用程式需求一致。
3. 使用 Locator.ariaSnapshot
方法
locator.ariaSnapshot() 方法可讓您以程式設計方式,建立定位器範圍內可存取元素的 YAML 表示法,這對於在測試執行期間動態產生快照特別有用。
範例:
const snapshot = await page.locator('body').ariaSnapshot();
console.log(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]