只有累積,沒有奇蹟

2022年9月3日 星期六

[Testing] Playwright : 現代化的跨瀏覽器自動化測試框架

前言
在前一篇 [Tool] END-TO-END Test 測試工具 - Playwright 介紹好用的 open source 工具 Playwright,過了一年 Playwright 功能越來越強大自己也花了點時間研究,這篇文章就來針對這套好用的開源工具繼續推坑,若有問題歡迎提出來一起討論。

E2E Testing
在提到 Playwright 之前,想要先提一下什麼是 end to end testing,查詢 wiki 可以得到下列解釋

End-to-End Testing (E2E testing) refers to a software testing method that involves testing an application’s workflow from beginning to end. This method basically aims to replicate real user scenarios so that the system can be validated for integration and Data Integrity.
它是軟體開發生命週期(SDLC)中使用的一種方法,目標是模擬真實用戶場景從頭到尾的樣子,目的是為了確保子系統案預期工具與行為。上述聽起來可能會覺得很抽象,或者是可能在過去工作上聽過很多不同的名詞,聽完上述描述可能更容易讓人混淆,像是單元測試、E2E 測試、整合測試與 UI 測試,那麼這幾個有什麼不同呢 ? 我們可以透過這張圖來讓大家更容易了解這之間的差異

圖片來源 : Microservices Testing Strategies, Types & Tools: A Complete Guide

這是一張經典的測試金三角圖,裡面說明了單元測試、整合測試、E2E 測試、與 UI 測試之間的差異
  • 單元測試 : 紅色框部分,開發人員在撰寫程式時針對模組進行驗證的測試
  • 整合測試 : 藍色框部分,不同模組之間呼叫行為是否符合預期,上圖例子是前端與後端開發完後進行測試動作
  • E2E 測試 : 橘色框部分,上圖例子是前端與後端開發完後,再與其他服務(Service) 及資料庫多個服務進行測試
  • UI 測試 : 灰色框部分,上圖例子是使用 Client App 來呼叫後面服務(Service),驗證功能是否如預期
核心概念都是透過「預期結果(expect)」和「真實結果」去做比對,驗證兩者是否相同,不同測試就會驗證失敗再請工程師去察看哪邊出了問題要進行修正的動作。了解這些測試可能的差異之後,在實際執行上還要考慮的點是測試範圍、時間、成本等三個重要因素,因為各自所測試的守備範圍與顆粒度不同,勢必也會影響到測試人員或是開發人員所花費的時間,進而也會有執行成本的議題產生,因此在執行上也須要多考量這些因素。


E2E Testing 挑戰
在執行上可能會遇到很多大大小小的挑戰,我這裡列出我覺得在執行上可能比較重要的兩點 : 瀏覽器支援螢幕解析度

瀏覽器支援
由於使用者習慣的不同,所在國家政策與安全考量不同,因此在瀏覽器的分布上是相對沒那麼集中,如果要在測試時支援多個瀏覽器可能遇到的挑戰是在測試時就要在不同的瀏覽器上進行測試,來看其功能與 UI畫面是否與預期長的相同,功能不會有異常與意外,要花費的時間勢必要多少時間。

螢幕解析度
談完瀏覽器,下一個要關心的議題是螢幕解析度的部分。越來越多人使用手機與平板來瀏覽網頁,大家在使用的 Device 的螢幕尺寸與解析度都不相同,因此開發出來的網頁要如何在不同的螢幕正常呈現也是很重要的。
圖片來源 : Infographic: Fragmentation in OS, browsers, and devices

簡單總結一下 E2E 測試會遇到的挑戰
  • 瀏覽器 : 瀏覽器的種類型態不同,開如何支援與決定不支援那些 ?
  • 學習曲線 : 簡單來說就是 E2E 測試工具好不好學,是不是容易上手對團隊來說是個重要的議題
  • 穩定性 : E2E 測試可能是一直需要持續修改的,要在每次執行的過程可以重複執行不出錯,資料的準備也是重要的關鍵
  • 維護成本 : 隨著產品功能不斷的迭代,程式碼會一直不斷的修改,要如何確保測試案例可以一直正常執行,或是當心功能上線時可以快速進行相關調整也很重要


Playwright
Playwright 是一套現代化可靠的 e2e 測試工具,他是由微軟開源的,第一個版本是由微軟在 2019 年底 release,經過兩年的時間越來越火紅。根據熱門 Best of JS 網站的資料顯示,在 Testing tools 中 Playwright 佔據第一名,可以說是相當地受到開發者的歡迎與喜愛。

Why Playwright ?
Playwright 有很多強大的功能與特性,我這邊有整理自己覺得對開發者來說重要的六大特性,分別是
  • Cross Browser
  • Cross Language
  • Auto Retry/wait
  • Browser Contexts
  • Tracing
  • Powerful Tooling
接下來依據這六個特性來做簡單的說明


Cross Browser
Playwright 支援了所有現代化的 render 引擎,包括 Chromium, WebKit 和 Firefox,因此幾個主流的瀏覽器像是 Chrome、Edge、Firefox、Opera 都支援。如果要對網頁做相容信測試 Playwright 是一个很好的選擇。也解決了前面提到 E2E 挑戰的第一點。

Cross Language
支援多程式語言,提供多種程式語言的 API,包括 TypeScript、JavaScript、Python、.NET 和 Java。跨程式語言帶來甚麼好處呢 ? 可以選擇自己熟悉的程式語言開發測試的腳本。這邊官方有更詳細的說明,詳細可以到 playwright.dev 看更詳細的資料。

Auto Retry/wait
舉個實際案例,假設我們有個登入頁面,登入 page 有帳號密碼欄位要輸入其中帳號欄位要輸入時會自動檢查格式內容是否正確,檢查邏輯是在檢查格式過程中登入按鈕是沒辦法輸入的。
一般來說,我們所撰寫的測試腳本會按照你的程式碼逐行往下執行(肉眼跟不上的速度),因此在沒有 autowait 功能的情況底下,這種測試案例在執行上是很容易執行失敗的(因為無法按下登入按鈕),失敗原因是前面提到的預期結果與實際測試結果不同。在過去可能會在測試腳本遇到時等待一段時間再繼續 (thread.sleep n 秒),等待一段時間之後再按下按鈕,但這個 N 秒在每個環境可能會有所不同需要團隊討論,太長會影響測試腳本的執行總時間,太短則很容易遇到測試腳本執行失敗的狀況,playwright 內建 auto wait 功能讓大家可以忽略這件事情,可以更專注的撰寫重要邏輯上。


Browser Contexts

它能夠在單個瀏覽器中提供互相隔離的執行環境,特別是在測試多個頁面時這個特性是相當重要的,可以透過腳本很方便的實現網頁頻繁的切換。每個頁面可以在各自的 context 中執行不會互相干擾,包括 cookies 等資訊都是隔離開的。
上述內容或許有點抽象,舉個實際的例子可能會比較好理解,假設公司產品是開發類似通訊軟體類(IM),要測試 Web 版的聊天功能,在這情境下就需要開啟兩個聊天畫面來測試聊天功能是否正常。腳本上可能是開啟兩個瀏覽器做登入,登入之後透過 A 傳給 B 看訊息內容是否有正確的送達。在過去沒有此功能可能要先登出 A 在重新登入 B 進行驗證。現在有這功能就可以省下登入登出時間快速驗證效果與功能正確性。


Tracing
跑測試時可能會遇到當你的測試案例執行失敗,要如何快速的定位問題,並提供給開發團隊的 RD 同仁呢 ?
反過來說,如果可以知道在哪個步驟或是地方知道執行之敗,這樣對於盤查問題跟問題定位上會有更大的幫助,開發團隊可以更快地找到哪邊有問題,並針對有問題的地方盤查傳遞的 http request 內容或是 request body 參數是甚麼,可以更快速的找到問題並進行修正,對於修復問題的時間可以大大的提升。playwright 有提供 Trace Viewer 強大的 GUI Tools,提供截圖、action、source code 及 screenshots 等資訊讓開發人員可以定位問題,詳細可以參考 trace-viewer


Powerful Tooling
Test Generator : 測試團隊可能相較於開發人員,有些是比較沒有程式開發相關背景的。playwright 提供 Codegen 功能,可以透過瀏覽器錄製測試步驟,產生程式碼。程式碼可以在工具平台上重複的進行測試的動作,對於測試人員的 Loading 也相對較輕鬆。
另外也提供測試報告,團隊可以透過測試報告來了解一些潛在的問題,舉例說當你發現測試時間過長,就可以透過測試報告觀看每一段所花費多久,找到可能可以改善的地方或是優化的點。



Demo : Test Generator
來透過 codegen 功能來試試看它是如何產生代馬的,在此步驟可以先開啟命令提示字元輸入安裝 playwright 指令
npx playwright install
接著輸入內建的 codegen 指令,來錄製操作步驟與產生其相關的語法
npx playwright codegen demo.playwright.dev/todomvc
會跳出瀏覽器視窗,接著可以在是窗框中輸入 keyword,在這案例中我輸入 test、this is a book,可以發現在右方框中會同步產生相關語法,如下圖所示
你也可以錄製在 google 輸入關鍵字,接著再去點選特定的查詢結果,下面代碼是透過錄製開啟 google 首頁,接著查詢 COSCUP MEETUP 研討會連結,進入到連結後找到 "" 分享 SESSION 內容頁面,並將其結果儲存下來
public static async Task Main()
{
	await GoogleCOSCUP();
}

private static async Task GoogleCOSCUP()
{
	using var playwright = await Playwright.CreateAsync();
	await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
	{
		Headless = false,
	});
	var context = await browser.NewContextAsync();
	// Open new page
	var page = await context.NewPageAsync();
	// Go to https://www.google.com/?gws_rd=ssl
	await page.GotoAsync("https://www.google.com/?gws_rd=ssl");
	// Click [aria-label="搜尋"]
	await page.Locator("[aria-label=\"搜尋\"]").ClickAsync();
	// Fill [aria-label="搜尋"]
	await page.Locator("[aria-label=\"搜尋\"]").FillAsync("coscup");
	// Press Enter
	await page.Locator("[aria-label=\"搜尋\"]").PressAsync("Enter");
	//await page.WaitForURLAsync("https://www.google.com/search?q=coscup&source=hp&ei=yvHlYsjhDbmRr7wPt4OysAI&iflsig=AJiK0e8AAAAAYuX_2qYZgkQ_Hm0nRenoqQN3m5Lu5HiY&ved=0ahUKEwjI7q_lkqL5AhW5yIsBHbeBDCYQ4dUDCAo&uact=5&oq=coscup&gs_lcp=Cgdnd3Mtd2l6EAMyCwgAEIAEELEDEIMBMgQIABADMgUIABCABDIECAAQAzIECAAQAzIECAAQAzIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQ6CAgAEIAEELEDOhEILhCABBCxAxCDARDHARDRAzoOCC4QgAQQsQMQxwEQ0QM6CwguEIAEELEDEIMBOhQILhCABBCxAxCDARDHARDRAxDUAjoICAAQsQMQgwE6CwguEIAEEMcBEK8BUL4EWJcTYNIaaAJwAHgAgAGZAYgB0QWSAQM0LjOYAQCgAQGwAQA&sclient=gws-wiz");
	// Click text=COSCUP 2022 | Conference for Open Source Coders, Users ...
	await page.Locator("text=COSCUP 2022 | Conference for Open Source Coders, Users ...").ClickAsync();
	await page.WaitForURLAsync("https://coscup.org/2022/zh-TW/");
	// Click a:has-text("議程表") >> nth=1
	await page.Locator("a:has-text(\"議程表\")").Nth(1).ClickAsync();
	await page.WaitForURLAsync("https://coscup.org/2022/zh-TW/session");
	// Click text=2022 / 7 / 31
	await page.Locator("text=2022 / 7 / 31").ClickAsync();
	// Click text=現代化 End to End 測試工具 : Playwright
	await page.Locator("text=現代化 End to End 測試工具 : Playwright").ClickAsync();
	await page.WaitForURLAsync("https://coscup.org/2022/zh-TW/session/3QNTQT");

	await context.Tracing.StopAsync(new()
	{
		Path = "trace.zip"
	});

}
程式說明
  • Line 9 : Headless,透過步調用瀏覽器的渲染引擎,可以提高其腳本執行速度與測試效率
  • Line 17 : 開啟 Google 首頁
  • Line 21 : 輸入 COSCUP 並按下搜尋
  • Line 26 : 點擊 COSCUP 2022 連結
  • Line 29 & 32 : 點擊議程表 & 選擇 7/31 日期
  • Line 37 : 將其結果儲存下來,檔名為 Trace.zip

以上簡單介紹到這邊,有興趣的朋友歡迎可以試試看 :)


感想
如果想了解更多,可以參考 #30DaysOfPlaywright 日後有機會可以做進一步的研究跟分享,以上如果有不清楚的地方歡迎一起討論,hope it helps !

參考
playwright.dev

0 意見:

張貼留言

Copyright © m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com