《最新出爐》系列初窺篇-Python+Playwright 自動化測試-2-playwright 的 API 及其他知識

北京-宏哥發表於2024-11-01

1.簡介

上一篇宏哥已經將 Python+Playwright 的環境搭建好了,而且也簡單的演示了一下三款瀏覽器的啟動和關閉,是不是很簡單啊。今天主要是把一篇的中的程式碼進行一次詳細的註釋,然後說一下 playwright 的 API 和其他相關知識點。那麼首先將上一篇中的程式碼進行一下詳細的解釋。

2.程式碼解釋

2.1 建立瀏覽器物件

 '''預設為無頭瀏覽器方式啟動  '''
browser = p.webkit.launch(headless=False)

2.2 建立 page 物件

一般來說,一個 page 對應一個瀏覽器選項卡,而 Page 物件的作用在於和頁面的內容進行互動,以及導航和載入新的頁面。這點和 selenium 有點像,也可以說是比 selenium 劃分的更加細緻精確。

page = browser.new_page()

2.3 其他

其他的是一些選擇器和操作方法,在後續的文章中宏哥都會一一的介紹到。

3.playwright 的 API

Playwright 支援同步和非同步兩種 API,使用非同步 API 需要匯入 asyncio 庫,它是一個可以用來實現 Python 協程的庫,更詳細介紹可參考 Python 協程 。我們可以根據自己的偏好選擇適合的模式。

3.1 同步與非同步模式原理

同步操作方式:在程式碼執行時,程式會阻塞等待每個操作執行的結果,直到該操作執行結束才能繼續執行後面的程式碼。同步程式碼容易理解和編寫,但如果在網路請求等 I/O 操作時會造成大量的等待時間,影響程式的執行效率。

非同步操作方式:在程式碼執行時,當遇到需要等待操作執行的時候,程式不會被阻塞,而是繼續執行其他的程式碼。當該操作執行的結果返回時,程式會自動跳回去接著執行之前被暫停的程式碼。非同步操作雖然需要一定的學習成本,但可以提升程式的執行效率。

3.1.1 同步模式

· 直接順序執行測試邏輯,直到完成。

· 使用上下文管理器或啟動/關閉方法控制瀏覽器生命週期。

· 簡單易用,適合同步測試場景。

· 但無法實現非同步或重疊的測試邏輯。

3.1.2 非同步模式

· 利用 asyncio 模組以非同步非阻塞方式執行測試邏輯。

· 瀏覽器啟動/關閉和大多數 Playwright API 也是非同步的,需要 await。

· 可以實現複雜的非同步或重疊測試邏輯。

· 但較難除錯,有一定學習成本。

3.2 同步和非同步的概念

同步:傳送一個請求,等待返回,然後再傳送下一個請求。

非同步:傳送一個請求,不等待返回,隨時可以再傳送下一個請求。

3.3 同步和非同步實踐

3.3.1 測試用例

宏哥這裡假設一共有 2 條測試用例,用例 1 步驟如下:
1)chrome 瀏覽器開啟百度
2)搜尋框輸入 “test”
3)點選百度一下搜尋
4)點選搜尋結果的第 2 頁
用例 2 步驟:
1)chrome 瀏覽器開啟搜狗搜尋
2)搜尋框輸入 “test”
3)點選搜狗搜尋
4)點選搜尋結果的第 2 頁

3.3.2 同步

這裡我們使用 sync_playwright 上下文管理器同步啟動 Playwright,然後編寫同步測試邏輯。

3.3.2.1 參考程式碼

根據上述測試用例編寫自動化測試指令碼程式碼如下:

# coding=utf-8🔥

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2023-05-18
@author: 北京-宏哥   QQ交流群:705269076
Project: 《最新出爐》系列初窺篇-Python+Playwright自動化測試-2-playwright的API及其他知識公眾號:北京宏哥
'''

# 3.匯入模組
import time
from playwright.sync_api import sync_playwright


def 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))

3.3.2.2 執行程式碼

執行程式碼後,控制檯列印,如下圖所示:

3.3.3 非同步

這裡我們使用 asyncio 模組非同步啟動 Playwright,然後編寫非同步測試邏輯。需要使用 await 關鍵字標識非同步操作。

3.3.3.1 參考程式碼

根據上述測試用例編寫自動化測試指令碼程式碼如下:

# coding=utf-8🔥

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2023-05-18
@author: 北京-宏哥   QQ交流群:705269076
公眾號:北京宏哥
Project: 《最新出爐》系列初窺篇-Python+Playwright自動化測試-2-playwright的API及其他知識
'''

# 3.匯入模組
import asyncio
import time

from playwright.async_api import async_playwright


async 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))

3.3.3.2 執行程式碼

執行程式碼後,控制檯列印,如下圖所示:

透過對比同步和非同步的執行時間可以看到,使用非同步程式設計的方式可以顯著提升測試效率。

4.headless 模式

在 launch 方法的引數中新增 headless=False playwright 預設是無頭模式執行,True 是無頭模式,False 是有頭模式,即在電腦上能看到瀏覽器的執行介面。預設情況下,Playwright 以無頭模式執行瀏覽器。要檢視瀏覽器 UI,請 headless=False 在啟動瀏覽器時傳遞標誌。有頭模式適用於除錯,而無頭模式適用於 CI / cloud 執行。

4.1headless

headless 無頭模式執行瀏覽器示例:

# coding=utf-8🔥

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2023-05-19
@author: 北京-宏哥   QQ交流群:705269076
公眾號:北京宏哥
Project: 《最新出爐》系列初窺篇-Python+Playwright自動化測試-2-playwright的API及其他知識
'''

# 3.匯入模組

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()          # 啟動 chromium 瀏覽器
    page = browser.new_page()              # 開啟一個標籤頁
    page.goto("https://www.baidu.com")     # 開啟百度地址
    print(page.title())                    # 列印當前頁面title
    page.click("input[name=\"wd\"]")       # 點選輸入框
    page.fill("input[name=\"wd\"]", "chromium")  # 在輸入框輸入瀏覽器名字
    page.screenshot(path=f'example-{p.chromium.name}.png')
    browser.close()                        # 關閉瀏覽器物件

4.2 非 headless

非 headless 無頭模式執行瀏覽器示例:

# coding=utf-8🔥

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2023-05-19
@author: 北京-宏哥   QQ交流群:705269076
公眾號:北京宏哥
Project: 《最新出爐》系列初窺篇-Python+Playwright自動化測試-2-playwright的API及其他知識
'''

# 3.匯入模組

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)          # 啟動 chromium 瀏覽器
    page = browser.new_page()              # 開啟一個標籤頁
    page.goto("https://www.baidu.com")     # 開啟百度地址
    print(page.title())                    # 列印當前頁面title
    page.click("input[name=\"wd\"]")       # 點選輸入框
    page.fill("input[name=\"wd\"]", "chromium")  # 在輸入框輸入瀏覽器名字
    page.screenshot(path=f'example-{p.chromium.name}.png')
    browser.close()                        # 關閉瀏覽器物件

5.小結

5.1 同步和非同步

Python Playwright 支援同步和非同步兩種操作方式。

同步操作方式:在程式碼執行時,程式會阻塞等待每個操作執行的結果,直到該操作執行結束才能繼續執行後面的程式碼。同步程式碼容易理解和編寫,但如果在網路請求等 I/O 操作時會造成大量的等待時間,影響程式的執行效率。

非同步操作方式:在程式碼執行時,當遇到需要等待操作執行的時候,程式不會被阻塞,而是繼續執行其他的程式碼。當該操作執行的結果返回時,程式會自動跳回去接著執行之前被暫停的程式碼。非同步操作雖然需要一定的學習成本,但可以提升程式的執行效率。

Python Playwright 預設使用非同步操作方式。可以透過使用 await 關鍵字或 async with 語法來定義非同步操作,或者使用 sync 關鍵字來定義同步操作。

今天這一篇主要給大家分享了 playwright 的同步和非同步、有頭和無頭。它們各有利弊,要靈活掌握其適合使用的測試場景。好了,今天時間也不早了,宏哥就講解和分享到這裡,感謝您耐心的閱讀,希望對您有所幫助。

相關文章