Bot Style Tests VS Page Objects


Bot Style Tests

https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests

盡管 Page Objects 在你的測試中減少重復的方式是非常有用的,這並不總是一個團隊願意遵循的模式,另一種方法是遵循更command-like的測試風格。

一個bot是基於Selenium APIs 面向操作的抽象。這意味着如果你發現命令對你的應用程序沒有做正確的事情,改變他們很容易。

# bst.py
from selenium.webdriver.remote.webdriver import WebDriver


class ActionBot:
    def __init__(self, driver: WebDriver) -> None:
        self.driver = driver

    def click(self, *locator):
        self.driver.find_element(*locator).click()

    def submit(self, *locator):
        self.driver.find_element(*locator).submit()

    def type(self, *locator, text):
        elem = self.driver.find_element(*locator)
        elem.clear()
        elem.send_keys(text)
  • 這其實相當於對Selenium API 的再次封裝。
# test_bst.py
from selenium.webdriver.common.by import By
from bst import ActionBot


def test_bst(browser):
    browser.get("http://www.baidu.com")

    action_bot = ActionBot(browser)
    action_bot.type(*(By.ID, "kw"), text="bot style tests")
    action_bot.click(*(By.ID, "kw"))
    time.sleep(5)

*(By.ID, "kw") - 這種寫法不太常見,我單純是為遵循文檔上的寫法。

Page Objects

page objects 相信大家非常熟悉了,為了保持討論的完整性,我還是給出例子。

from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.common.by import By


class Page:
    def __init__(self, driver: WebDriver) -> None:
        self.driver = driver

    @property
    def search_input(self):
        return self.driver.find_element(By.ID, "kw")

    @property
    def search_button(self):
        return self.driver.find_element(By.ID, "su")
  • 將每個元素封裝為一個類方法。
from po import Page

def test_po(browser):
    browser.get("http://www.baidu.com")
    page = Page(browser)
    page.search_input.send_keys("bot style tests")
    page.search_button.click()
  • 對不同的元素對象進行操作。

Bot Page

Bot Page是什么鬼?其實我們可以把上面的兩種設計模式整合一下。在Page層既包含元素又包含動作。Bot Page是隨便取的。

from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.common.by import By


class BotPage:
    def __init__(self, driver: WebDriver) -> None:
        self.driver = driver

    def type_search_input(self, text):
        self.driver.find_element(By.ID, "kw").send_keys(text)

    def click_search_button(self):
        self.driver.find_element(By.ID, "su").click()

  • 元素定位和操作封裝到一起。
from po import BotPage

def test_bst_po(browser):
    browser.get("http://www.baidu.com")
    page = BotPage(browser)
    page.type_search_input("bot style tests")
    page.click_search_button()
  • 這種方式就是最完美的嗎?不是,這相當於強行將元素定位和操作綁定。但有時候一個元素可能有多種操作,比如輸入框,clear()send_keys()submit() 都是可以的。

混用

三種模式並非相互對立,可以混合使用。比如,第一種和第三種混用。

from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.common.by import By


class ActionBot:
    """bot style"""
    def __init__(self, driver: WebDriver) -> None:
        self.driver = driver

    def click(self, *locator):
        self.driver.find_element(*locator).click()

    def submit(self, *locator):
        self.driver.find_element(*locator).submit()

    def type(self, *locator, text):
        elem = self.driver.find_element(*locator)
        elem.clear()
        elem.send_keys(text)


class BotPage(ActionBot):
    """ bot Page """
    def type_search_input(self, text):
        self.type(*(By.ID, "kw"), text=text)

    def click_search_button(self):
        self.click(By.ID, "su")
  • bot Page 去繼承 Action bot,bot page 寫起來就簡單一些了。

poium

當然,最簡單的仍然是 poium。

https://github.com/SeldomQA/poium

from poium import Page, Element, CSSElement

class PoiumPage(Page):
    search_input = Element(name='wd')
    search_button = Element(id_='su')

class CssPage(Page):
    search_input = CSSElement('#kw')
    search_button = CSSElement('#su')
  • 他幾乎是Page Objects設計模式的天花板了。程序員高質量Page objects測試庫。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM