Selenium4+Python3系列(十一) - Page Factory設計模式

久曲健發表於2022-12-05

寫在前面:

Page Object模式,目的是將元素定位和元素操作分層,只接觸測試內容,不寫基礎內容,便於後續對自動化測試用例體系的維護,這是中心思想,也是核心。

那麼我們繼續將簡潔延續,這裡沿用JavaPage Factory模式思想,旨在減少程式碼冗餘,簡單易用,具有高度的可擴充套件能力。

所以,這裡我們使用基於PythonPage Factory設計模式

Page Factory的使用

作用:

  • 支援以註解的方式定義元素
  • 支援同一個元素多種定位方式
  • 支援動態的定位方式

1、安裝

pip install pythium

2、使用 Page Factory 模式將頁面元素分離

我們將繼續沿用Page Object模式的風格,這裡我又加了一層自己暫時定義叫基礎層,現在就變成了四層:基礎層、物件層、操作層、業務層。

下面將舉例說明Page Factory設計模式,以登陸功能為例,來做進一步講解。

3、基礎層

用來存放driver及初始化使用,示例程式碼如下:

# -*- coding: utf-8 -*-
"""
@Time : 2022/12/5 21:07
@Auth : 軟體測試君
@File :BasePage.py
@IDE :PyCharm
@Motto:ABC(Always Be Coding)
"""
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

from pagefactory.LoginPage import LoginPage


class BasePage(object):
    """
    用來存放driver及初始化使用
    """

    def __init__(self) -> None:
        """
        初始化driver
        """
        self.driver = webdriver.Chrome(ChromeDriverManager().install())
        self.driver.maximize_window()

    def open_url(self, url: str) -> None:
        """
        開啟專案首頁
        :param url:
        :return:
        """
        self.driver.get(url)

    def quit_browser(self) -> None:
        """
        退出瀏覽器
        :return:
        """
        self.driver.quit()

    def get_LoginPage(self) -> LoginPage:
        # 返回登陸實體
        return LoginPage(self.driver)

4、物件層

用於存放頁面元素定位和控制元件操作,示例程式碼如下:

# -*- coding: utf-8 -*-
"""
@Time : 2022/12/5 21:13
@Auth : 軟體測試君
@File :LoginPage.py
@IDE :PyCharm
@Motto:ABC(Always Be Coding)
"""
import time

from pythium import find_by, Page
from selenium.webdriver.remote.webelement import WebElement


class LoginPage(Page):
    """
    用於存放頁面元素定位和控制元件操作
    """

    # 定位使用者名稱元素
    @find_by(css="input[type='text']")
    def username_el(self) -> WebElement: ...

    # 定位密碼元素
    @find_by(css="input[type='password']")
    def password_el(self) -> WebElement: ...

    # 定位登陸元素
    @find_by(name="submit")
    def loginbtn_el(self) -> WebElement: ...

    # 定位錯誤資訊元素
    @find_by(id_="alert")
    def errormsg_el(self) -> WebElement: ...

    # 輸入使用者名稱
    def send_username(self, username: str):
        """
        輸入使用者名稱
        :param self:
        :param username:
        :return:
        """
        self.username_el().clear()
        self.username_el().send_keys(username)

    # 輸入密碼
    def send_password(self, password: str):
        """
        輸入密碼
        :param self:
        :param password:
        :return:
        """
        self.password_el().clear()
        self.password_el().send_keys(password)

    # 點選登陸按鈕
    def click_loginbtn(self):
        """
        點選登陸按鈕
        :return:
        """
        self.loginbtn_el().click()

    # 獲取錯誤資訊
    def get_erorMsg(self) -> str:
        """
        獲取錯誤資訊
        :return:
        """
        time.sleep(1)
        return self.errormsg_el().text

5、操作層

則是一些封裝好的功能用例模組,也可以理解成我們寫測試用例的步驟,示例程式碼如下:

# -*- coding: utf-8 -*-
"""
@Time : 2022/12/5 21:33
@Auth : 軟體測試君
@File :LoginAction.py
@IDE :PyCharm
@Motto:ABC(Always Be Coding)
"""
from pagefactory.BasePage import BasePage


class LoginAction(object):
    """
    登陸操作
    """

    def login(self, username: str, password: str):
        """
        登陸操作
        :param username: 使用者名稱
        :param password: 密碼
        :return:
        """
        basepage = BasePage()
        basepage.open_url('http://localhost:8080/login')
        basepage.get_LoginPage().send_username(username)
        basepage.get_LoginPage().send_password(password)
        basepage.get_LoginPage().click_loginbtn()
        msg = basepage.get_LoginPage().get_erorMsg()
        basepage.quit_browser()
        return msg

6、業務層

則是我們真正的測試用例的操作部分,示例程式碼如下:

# -*- coding: utf-8 -*-
"""
@Time : 2022/12/5 21:40
@Auth : 軟體測試君
@File :TestLogin.py
@IDE :PyCharm
@Motto:ABC(Always Be Coding)
"""
import unittest

from pagefactory.LoginAction import LoginAction


class TestLogin(unittest.TestCase):
    """
    測試登陸功能
    """
    def test_login(self):
        msg = LoginAction().login("1", "1")
        self.assertEquals(msg, "使用者名稱或密碼錯誤!")

從以上程式碼看,如果頁面元素髮生變化,我們在對應類裡修改對應元素即可,而操作和業務層流程類及用例都不用改,如果僅是業務流程更改,只需要維護業務層流程類業務指令碼,其他幾個類都不用改,從而做到了很好的將頁面、元素、指令碼進行了分離。

至此,關於Page Factory的使用分享完畢,有興趣的同學可以自行擴充。

寫在最後

又有很久沒有更文了,因為一直都是996工作制,很難有時間去寫文章,這裡還請各位粉絲朋友理解,不過,我會努力持續更文。

我是六哥,如果覺得文章對您有幫助,請繼續關注我,原創不易,不求打賞,只求轉發!?

相關文章