學(xué)習(xí)了 Cypress 工具后,突然發(fā)現(xiàn)目前很流行的 Playwright,Playwright 提供了一套功能強(qiáng)大且靈活的工具,使得在不同瀏覽器上執(zhí)行自動(dòng)化測(cè)試變得更加容易和可靠,這使得 Playwright 成為很多開發(fā)者選擇的首選工具之一。
這么厲害的工具必須看看!! 以此來(lái)記錄自己學(xué)習(xí) Playwright 過程中的一些內(nèi)容围段。
環(huán)境準(zhǔn)備
學(xué)習(xí)一個(gè)新的工具框架,必須優(yōu)先閱讀官方文檔投放。閱讀?Playwright 官方文檔奈泪,考慮使用 Python + Playwright 進(jìn)行學(xué)習(xí),創(chuàng)建一個(gè)新的 Python虛擬環(huán)境(我使用 IDEA 進(jìn)行開發(fā)灸芳,還可選擇使用 VS Code / Pycharm ):
安裝 Playwright: 使用 npm 進(jìn)行安裝涝桅。打開終端并運(yùn)行以下命令:
npm init playwright@latest
命令途中需要我們對(duì)以下內(nèi)容進(jìn)行選擇:
在 TypeScript 或 JavaScript 之間進(jìn)行選擇(默認(rèn)為 TypeScript,TypeScript 提供了更強(qiáng)大的開發(fā)工具和更豐富的功能烙样,尤其適用于大型項(xiàng)目和需要嚴(yán)格類型檢查的場(chǎng)景冯遂,JavaScript 則更適合小型項(xiàng)目和快速原型開發(fā));
您的測(cè)試文件夾的名稱(如果您的項(xiàng)目中已有測(cè)試文件夾谒获,則默認(rèn)為測(cè)試或 e2e)蛤肌;
添加 GitHub Actions 工作流程以輕松在 CI 上運(yùn)行測(cè)試壁却;
安裝 Playwright 瀏覽器(默認(rèn)為 true)。
Playwright 將下載所需的瀏覽器并創(chuàng)建一些配置文件裸准,可以在playwright.config中添加Playwright 配置展东,包括修改想要運(yùn)行 Playwright 的瀏覽器。如果在現(xiàn)有項(xiàng)目中運(yùn)行測(cè)試炒俱,那么依賴項(xiàng)將直接添加到package.json琅锻。tests文件夾包含一個(gè)基本示例測(cè)試,可幫助我們開始測(cè)試向胡。有關(guān)更詳細(xì)的示例,可查看tests-examples包含為測(cè)試待辦事項(xiàng)應(yīng)用程序而編寫的測(cè)試的文件夾惊完。
簡(jiǎn)單測(cè)試
直接快速測(cè)試tests文件夾中的基本示例:
npx playwright test
此測(cè)試在無(wú)瀏覽器模式下運(yùn)行僵芹,這意味著運(yùn)行測(cè)試時(shí)不會(huì)打開瀏覽器。測(cè)試結(jié)果和測(cè)試日志將顯示在終端中小槐。
測(cè)試完成后拇派,將生成一個(gè)HTML 報(bào)告器,其中顯示完整的測(cè)試報(bào)告凿跳,允許按瀏覽器件豌、通過的測(cè)試、失敗的測(cè)試控嗜、跳過的測(cè)試和不穩(wěn)定測(cè)試來(lái)過濾報(bào)告茧彤。可以單擊每個(gè)測(cè)試并探索測(cè)試的錯(cuò)誤以及測(cè)試的每個(gè)步驟疆栏。默認(rèn)情況下曾掂,如果某些測(cè)試失敗,將自動(dòng)打開 HTML 報(bào)告壁顶。
UI模式
即為headful 模式: 在此模式下珠洗,可以看到瀏覽器界面,就像正常使用瀏覽器一樣若专。這對(duì)于調(diào)試和觀察測(cè)試執(zhí)行過程非常有幫助许蓖。
npx playwright test --ui
Playwright + Python
Playwright 的原生版本是用 TypeScript 編寫的,并提供了 JavaScript 和 TypeScript 的 API调衰,因此可以使用這兩種語(yǔ)言來(lái)編寫測(cè)試腳本膊爪。Playwright 還提供了 Python 版本的 API,可以使用 Python 編寫和執(zhí)行自動(dòng)化測(cè)試腳本窖式。
使用Python版本蚁飒,需pip導(dǎo)入所需要的playwright:
pip install playwright
之后就可以import相應(yīng)的如playwright模塊中的函數(shù),使用 Python 語(yǔ)言編寫相應(yīng)的端到端測(cè)試萝喘。
同步與異步
在使用 Playwright + Python 進(jìn)行自動(dòng)化測(cè)試時(shí)淮逻,可以選擇同步或異步編程風(fēng)格琼懊,具體取決于個(gè)人偏好和項(xiàng)目的需求。
同步編程:
在同步編程中爬早,代碼按照順序執(zhí)行哼丈,每個(gè)操作都會(huì)等待前一個(gè)操作完成后再執(zhí)行下一個(gè)操作。使用同步編程風(fēng)格編寫的代碼通常更易于理解和調(diào)試筛严,因?yàn)樗鼈兪蔷€性執(zhí)行的醉旦。在 Python 中,可以使用同步的方式來(lái)編寫 Playwright 測(cè)試桨啃,例如使用time.sleep()來(lái)等待頁(yè)面加載完成或執(zhí)行其他操作车胡。
import time
from playwright.sync_api import sync_playwright #同步
with sync_playwright() as p:
????browser = p.chromium.launch()
????page = browser.new_page()
????page.goto("https://www.baidu.com")
????time.sleep(2) # 等待 2 秒
????browser.close()
異步編程:
在異步編程中,代碼可以并發(fā)執(zhí)行照瘾,不必等待前一個(gè)操作完成就可以執(zhí)行下一個(gè)操作匈棘。這樣可以提高程序的性能和響應(yīng)速度。使用異步編程風(fēng)格編寫的代碼通常更適合處理大量的并發(fā)任務(wù)析命。在 Python 中主卫,可以使用asyncio庫(kù)和異步版本的 Playwright API 來(lái)編寫異步代碼。
import asyncio
from playwright.async_api import async_playwright
async def main():
????async with async_playwright() as p:
????????browser = await p.chromium.launch()
????????page = await browser.new_page()
????????await page.goto("https://www.baidu.com") # 在異步編程中鹃愤,可以使用 await 來(lái)等待異步操作完成
????????await asyncio.sleep(2) # 等待 2 秒
????????await browser.close()
asyncio.run(main())
await
在 Python 的異步編程中簇搅,使用 await 關(guān)鍵字是為了讓當(dāng)前協(xié)程暫停執(zhí)行,等待另一個(gè)協(xié)程完成后再繼續(xù)執(zhí)行软吐。如果不使用 await瘩将,而是直接調(diào)用異步函數(shù),會(huì)導(dǎo)致當(dāng)前協(xié)程立即執(zhí)行下一行代碼关噪,而不等待異步操作完成鸟蟹,這可能會(huì)導(dǎo)致錯(cuò)誤或不符合預(yù)期的行為。
在這個(gè)例子中使兔,如果不使用await建钥,而是直接調(diào)用異步函數(shù),會(huì)導(dǎo)致當(dāng)前協(xié)程立即執(zhí)行下一行代碼虐沥,而不等待異步操作完成熊经。具體來(lái)說,如果不使用await來(lái)等待異步操作p.chromium.launch()欲险、browser.new_page()和page.goto()完成镐依,而是直接調(diào)用它們,可能會(huì)導(dǎo)致以下問題:
瀏覽器對(duì)象可能尚未完全初始化:在調(diào)用p.chromium.launch()后天试,瀏覽器對(duì)象可能尚未完全初始化槐壳,如果不等待它初始化完成,直接調(diào)用browser.new_page()喜每,可能會(huì)導(dǎo)致瀏覽器對(duì)象尚未準(zhǔn)備好务唐,從而引發(fā)錯(cuò)誤雳攘。
頁(yè)面可能尚未加載完成:在調(diào)用page.goto()后,頁(yè)面可能尚未完全加載完成枫笛,如果不等待頁(yè)面加載完成吨灭,直接執(zhí)行后續(xù)操作,可能會(huì)導(dǎo)致頁(yè)面尚未準(zhǔn)備好刑巧,從而導(dǎo)致無(wú)法獲取到預(yù)期的頁(yè)面內(nèi)容喧兄。
瀏覽器對(duì)象可能尚未關(guān)閉:在調(diào)用browser.close()后,如果不等待瀏覽器對(duì)象關(guān)閉完成啊楚,直接執(zhí)行后續(xù)操作吠冤,可能會(huì)導(dǎo)致瀏覽器對(duì)象尚未完全關(guān)閉,從而造成資源泄漏或其他問題恭理。
綜上所述咨演,不使用await來(lái)等待異步操作完成,可能會(huì)導(dǎo)致程序無(wú)法按預(yù)期執(zhí)行蚯斯,出現(xiàn)錯(cuò)誤或不符合預(yù)期的行為。因此饵较,在異步編程中拍嵌,使用await是確保異步操作按順序執(zhí)行和完成的關(guān)鍵。
總的來(lái)說循诉,同步編程更直觀易懂横辆,而異步編程更適合處理大規(guī)模的并發(fā)任務(wù)。在選擇編程風(fēng)格時(shí)茄猫,需要考慮項(xiàng)目的需求狈蚤、復(fù)雜度和性能要求。
Playwright codegen
Playwright 的 codegen 是一個(gè)非常實(shí)用的工具划纽,它可以幫助我們自動(dòng)生成執(zhí)行瀏覽器操作的代碼脆侮。該工具可以在瀏覽器中記錄用戶的交互操作,并將其轉(zhuǎn)換為 Playwright 腳本勇劣,這樣可以大大簡(jiǎn)化編寫自動(dòng)化測(cè)試腳本的過程靖避。
npx playwright codegen <url>
命令生成的代碼為 TypeScript 是因?yàn)?Playwright 本身是使用 TypeScript 編寫的,因此默認(rèn)情況下比默,codegen 工具生成的代碼也是 TypeScript幻捏。
如果想要生成 Python 語(yǔ)言的代碼,可以在執(zhí)行 codegen 命令時(shí)命咐,通過指定--target參數(shù)來(lái)指定生成的代碼語(yǔ)言篡九。例如:
npx playwright codegen --target=python <url>
這樣就可以生成 Python 語(yǔ)言的代碼了。同時(shí)醋奠,Playwright 的 codegen 工具會(huì)根據(jù)項(xiàng)目環(huán)境和執(zhí)行上下文來(lái)選擇適當(dāng)?shù)哪_本語(yǔ)言榛臼。具體來(lái)說伊佃,如果項(xiàng)目中已經(jīng)存在 TypeScript 或 Python 文件,那么 codegen 工具可能會(huì)選擇與項(xiàng)目中已有文件相同的腳本語(yǔ)言讽坏。這樣可以保持項(xiàng)目的一致性锭魔,并減少集成和維護(hù)的復(fù)雜性。在執(zhí)行 codegen 工具時(shí)路呜,它會(huì)檢查當(dāng)前的執(zhí)行上下文迷捧。例如,如果在 TypeScript 環(huán)境中運(yùn)行 codegen 工具胀葱,它可能會(huì)自動(dòng)選擇生成 TypeScript 代碼漠秋。同樣地,如果在 Python 環(huán)境中運(yùn)行 codegen 工具抵屿,它可能會(huì)自動(dòng)選擇生成 Python 代碼庆锦。
因?yàn)槲业捻?xiàng)目環(huán)境為 Python,當(dāng)我直接使用
playwright codegen <url>
可以直接生成 Python 語(yǔ)言的代碼轧葛。
同時(shí)搂抒,codegen還支持很多不同的參數(shù),如:
--device: 指定要模擬的設(shè)備類型(例如尿扯,iPhone X求晶、iPad、Galaxy S5)衷笋。
--geolocation: 指定地理位置坐標(biāo)芳杏,格式為緯度和經(jīng)度,例如37.7749,-122.4194辟宗。
--permissions: 指定要授予的權(quán)限爵赵,例如geolocation、notifications泊脐、midiSysex空幻。
--lang: 指定要使用的語(yǔ)言代碼,例如en-US容客、zh-CN氛悬。
--proxy: 指定代理服務(wù)器的地址和端口。
可以查閱官方文檔使用這些參數(shù)耘柱。
Playwright?Insepctor
在 Playwright?Insepctor 中如捅,我們可以直接生成包括 Pytest 或者async異步等不同類型的代碼(??),之后還會(huì)學(xué)習(xí) Pytest + Playwright的內(nèi)容调煎。