PlayWright(十二)- PO模式

2023-07-04 21:00:55

1、PO模式是什麼?

PO,即Page Object,直譯為頁面物件,代表 Web 應用程式的一部分
 
具體什麼意思呢,通俗來講,一個頁面有輸入、點選、搜尋功能,而且有很多頁面,這時候我們就採用每個頁面作為一個單獨的page物件來維護編寫,避免重複程式碼,層級也清晰,便於維護
 

2、以百度首頁搜尋為範例

我們以百度首頁的搜尋功能為例:
看下百度首頁的搜尋:
我們之前會這樣寫:開啟百度頁面,輸入內容,點選搜尋
from playwright.sync_api import sync_playwright

with sync_playwright() as playwright:  # 省略了start啟動
    browser = playwright.chromium.launch(headless=False, slow_mo=1000)  # 設定了每步等待時間為3s
    page = browser.new_page()  # 開啟一個頁面

    page.goto('https://www.baidu.com/')  # 開啟百度地址
    page.fill('#kw', 'test')             # 搜尋方塊輸入內容
    page.click('#su')                    # 點選搜尋
    browser.close()  # 省略了關閉playwright物件

 

 
那麼使用PO模式我們怎麼做呢?
 

01.目錄結構

首先先建立一個專案,看下專案的目錄結構
element目錄:
  • search_element:搜尋頁的定位元素
page目錄:封裝的全部頁面
  • search_page:搜尋頁面
result_image目錄:截圖的結果
testcase目錄:用例部分
  • test_search:搜尋功能的測試用例
tools目錄:工具包
  • conftest:這裡我們封裝前置和後置程式碼
 
 

02.element層

element程式碼層先來封裝search_element.py
"""
封裝百度搜尋方塊元素
"""

input_element = '#kw'  # 輸入框元素
click_element = '#su'  # 點選搜尋元素

 

03.tool層

我們接著封裝tools層
conftest.py寫什麼呢,我們可以把初始化瀏覽器的操作封裝下,還有關閉瀏覽器的操作,截圖等操作封裝成函數
"""
 前置後置操作:初始化操作
"""

from playwright.sync_api import sync_playwright


class SetupTeardown:
    """
      啟動瀏覽器
    """

    def __init__(self):
        self.p = sync_playwright().start()  # 建立playwright物件
        self.browser = self.p.chromium.launch(headless=False, slow_mo=1000)  # 啟動谷歌瀏覽器賦值給物件
        self.page = self.browser.new_page()  # 開啟一個頁面

    """
      關閉瀏覽器
    """

    def close(self):
        self.browser.close()  # 關閉瀏覽器物件
        self.p.stop()  # 關閉playwright物件釋放資源

    """
      截圖操作儲存到result_image目錄下
    """

    def screenshot(self, element, file_name):
        self.page.locator(element).screenshot(path=f"../result_image/{file_name}.png")

 

04.page層

我們接著封裝page層
搜尋頁我們繼承conftest,在search_page.py頁中首先初始化定位元素、封裝輸入、點選、搜尋操作,完善截圖操作
"""
封裝搜尋頁:初始化定位元素、重寫輸入操作、點選操作,截圖操作
"""
from tools.conftest import SetupTeardown


class SearchPage(SetupTeardown):
    """
    封裝定位元素
    """

    def __init__(self):
        super().__init__()  # 呼叫基礎頁面的建構函式,完成瀏覽器啟動和頁面開啟

    """
    去往搜尋頁
    """

    def navigate(self):
        self.page.goto('https://www.baidu.com/')

    """
    輸入操作
    """

    def input_element(self, element, keyword):
        self.page.fill(element, keyword)

    """
    點選操作
    """

    def click_element(self, element):
        self.page.click(element)

    """
    截圖搜尋結果頁
    """

 

05.testcase層

我們接著封裝testcase層,編寫test_search.py程式碼
這裡我們直接寫實際用例
"""
搜尋頁的測試用例
"""

from element.search_element import *  # 匯入搜尋頁的所有定位元素
from page.search_page import SearchPage  # 匯入搜尋頁物件

search_page = SearchPage()  # 初始化搜尋頁物件
search_page.navigate()  # 去往搜尋頁
search_page.input_element(input_search_element, 'playwright')  # 搜尋方塊輸入內容
search_page.click_element(click_search_element)  # 點選搜尋
search_page.screenshot('result_search_page')  # 截圖儲存
search_page.close()  # 關閉瀏覽器

 

執行一下,看下是否正常執行,我這裡看的搜尋結果截圖已經生成了
 

3、總結

PO模式看著非常麻煩,但是在較多頁面使用時,是便於我們理解程式碼便於維護的,比如上邊如果定位元素有變動,我們就去element層修改對應的定位元素,如果操作有變動,我們就去page層修改對應的頁面操作。而我們只需要在對應的testcase用例層編寫對應的用例即可,後續結合上pytest框架來管理用例會更方便