Playwright支持同步和異步兩種API,使用異步API需要導入asyncio庫,它是一個可以用來實現Python協程的庫,更詳細介紹可參考Python協程 。我們可以根據自己的偏好選擇適合的模式。
同步與異步模式原理
同步操作方式:在代碼執行時,程序會阻塞等待每個操作執行的結果,直到該操作執行結束才能繼續執行后面的代碼。同步代碼容易理解和編寫,但如果在網絡請求等 I/O 操作時會造成大量的等待時間,影響程序的執行效率。
異步操作方式:在代碼執行時,當遇到需要等待操作執行的時候,程序不會被阻塞,而是繼續執行其他的代碼。當該操作執行的結果返回時,程序會自動跳回去接著執行之前被暫停的代碼。異步操作雖然需要一定的學習成本,但可以提升程序的執行效率。
同步模式
· 直接順序執行測試邏輯,直到完成。
· 使用上下文管理器或啟動/關閉方法控制瀏覽器生命周期。
· 簡單易用,適合同步測試場景。
· 但無法實現異步或重疊的測試邏輯。
異步模式
· 利用asyncio模塊以異步非阻塞方式執行測試邏輯。
· 瀏覽器啟動/關閉和大多數Playwright API也是異步的,需要await。
· 可以實現復雜的異步或重疊測試邏輯。
· 但較難調試,有一定學習成本。
同步和異步的概念
同步:發送一個請求,等待返回,然后再發送下一個請求。
異步:發送一個請求,不等待返回,隨時可以再發送下一個請求。
同步和異步實踐
測試用例
假設一共有2條測試用例:
用例1步驟如下:
1)chrome瀏覽器打開百度
2)搜索框輸入“test”
3)點擊百度一下搜索
4)點擊搜索結果的第2頁
用例2步驟:
1)chrome瀏覽器打開搜狗搜索
2)搜索框輸入“test”
3)點擊搜狗搜索
4)點擊搜索結果的第2頁
同步
這里我們使用sync_playwright上下文管理器同步啟動Playwright,然后編寫同步測試邏輯。
參考代碼
根據上述測試用例編寫自動化測試腳本代碼如下:
import time
from playwright.sync_api import sync_playwrightdef testcase1():print('testcase1 start')with sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()page.goto("https://www.baidu.com/")print(page.title())page.fill("input[name=\"wd\"]", "test")page.click("text=百度一下")page.click("#page >> text=2")browser.close()print('testcase1 done')def testcase2():print('testcase2 start')with sync_playwright() as p:browser2 = p.chromium.launch(headless=False)page2 = browser2.new_page()page2.goto("https://www.sogou.com/")print(page2.title())page2.fill("input[name=\"query\"]", "test")page2.click("text=搜狗搜索")page2.click("#sogou_page_2")browser2.close()print('testcase2 done')start = time.time()
testcase1()
testcase2()
end = time.time()
print('Running time: %s Seconds' % (end - start))
異步
這里我們使用asyncio模塊異步啟動Playwright,然后編寫異步測試邏輯。需要使用await關鍵字標識異步操作。
參考代碼
根據上述測試用例編寫自動化測試腳本代碼如下:
import asyncio
import timefrom playwright.async_api import async_playwrightasync def testcase1():print('testcase1 start')async with async_playwright() as p:browser = await p.chromium.launch(headless=False)page = await browser.new_page()await page.goto("https://www.baidu.com/")print(await page.title())await page.fill("input[name=\"wd\"]", "test")await page.click("text=百度一下")await page.click("#page >> text=2")await browser.close()print('testcase1 done')async def testcase2():print('testcase2 start')async with async_playwright() as p:browser2 = await p.chromium.launch(headless=False)page2 = await browser2.new_page()await page2.goto("https://www.sogou.com/")print(await page2.title())await page2.fill("input[name=\"query\"]", "test")await page2.click("text=搜狗搜索")await page2.click("#sogou_page_2")await browser2.close()print('testcase2 done')async def main():task1 = asyncio.create_task(testcase1())task2 = asyncio.create_task(testcase2())tasks = [task1, task2]print('before await')await asyncio.gather(*tasks)start = time.time()
asyncio.run(main())
end = time.time()
print('Running time: %s Seconds' % (end - start))
通過對比同步和異步的運行時間可以看到,使用異步編程的方式可以顯著提升測試效率
Python Playwright 支持同步和異步兩種操作方式。
同步操作方式:在代碼執行時,程序會阻塞等待每個操作執行的結果,直到該操作執行結束才能繼續執行后面的代碼。同步代碼容易理解和編寫,但如果在網絡請求等 I/O 操作時會造成大量的等待時間,影響程序的執行效率。
異步操作方式:在代碼執行時,當遇到需要等待操作執行的時候,程序不會被阻塞,而是繼續執行其他的代碼。當該操作執行的結果返回時,程序會自動跳回去接著執行之前被暫停的代碼。異步操作雖然需要一定的學習成本,但可以提升程序的執行效率。
Python Playwright 默認使用異步操作方式。可以通過使用 await 關鍵字或 async with 語法來定義異步操作,或者使用 sync 關鍵字來定義同步操作。
headless 模式
在launch方法的參數中添加 headless=False playwright默認是無頭模式運行,True是無頭模式,False是有頭模式,即在電腦上能看到瀏覽器的運行界面。默認情況下,Playwright 以無頭模式運行瀏覽器。要查看瀏覽器 UI,請headless=False在啟動瀏覽器時傳遞標志。有頭模式適用于調試,而無頭模式適用于CI / cloud執行。
headless 無頭模式運行瀏覽器示例: 打開瀏覽器/不打開瀏覽器
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:# headless無頭模式運行瀏覽器示例: 不打開瀏覽器界面browser = p.chromium.launch()# 非headless無頭模式運行瀏覽器示例: 打開瀏覽器界面# browser = p.chromium.launch(headless=False) # 啟動 chromium 瀏覽器page = browser.new_page() # 打開一個標簽頁page.goto("https://www.baidu.com") # 打開百度地址print(page.title()) # 打印當前頁面titlepage.click("input[name=\"wd\"]") # 點擊輸入框page.fill("input[name=\"wd\"]", "chromium") # 在輸入框輸入瀏覽器名字page.screenshot(path=f'example-{p.chromium.name}.png')browser.close() # 關閉瀏覽器對象