Page Objects design pattern: 页面对象模式是为网页的每个部分创建一个对象,用面向对象的方式来操作网页元素。这种技术有助于在测试代码和实际与网页交互的代码之间建立分离。这种模式通常划分为三个类:Page,PageElements和Locators。
使用网页对象模式的好处:
- 测试用例更易读
- 减少重复代码的量
- 代码可重用,便于测试用例之间共享
- 封装变化,减少修改量
- Locators类
将网页元素的定位信息都封装在一个类里面,建议每个网页定义一个Locator类。
#locators.py
from selenium.webdriver.common.by import By
class MainPageLocators(object):
"""A class for main page locators. All main page locators should come here"""
SUBMIT_BUTTON = (By.ID, 'submit')
class SubPageLocators(object):
"""A class for other sub page locators."""
RESULT_TABLE= (By.ID, 'query_result')
- Elements类
实现对网页元素的读写通用操作。
#element.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
class BasePageElement(object):
"""Base page class that is initialized on every page object class."""
def __set__(self, obj, value):
"""Sets the text to the value supplied"""
driver = obj.driver
WebDriverWait(driver, 100).until(
lambda driver: driver.find_element(By.NAME, self.locator))
driver.find_element(By.NAME, self.locator).clear()
driver.find_element(By.NAME, self.locator).send_keys(value)
def __get__(self, obj, owner):
"""Gets the text of the specified object"""
driver = obj.driver
WebDriverWait(driver, 100).until(
lambda driver: driver.find_element(By.NAME, self.locator))
element = driver.find_element(By.NAME, self.locator)
return element.get_attribute("value")
- Page类
调用前面两个类,实现对每个网页的内容读取、点击等操作。
#page.py
from element import BasePageElement
from locators import MainPageLocators
class SearchTextElement(BasePageElement):
"""This class gets the search text from the specified locator"""
#The locator for search box where search string is entered
locator = 'q'
class BasePage(object):
"""Base class to initialize the base page that will be called from all
pages"""
def __init__(self, driver):
self.driver = driver
class MainPage(BasePage):
"""Home page action methods come here. I.e. Python.org"""
#Declares a variable that will contain the retrieved text
search_text_element = SearchTextElement()
def is_title_matches(self):
"""Verifies that the hardcoded text "Python" appears in page title"""
return "Python" in self.driver.title
def click_submit_button(self):
"""Triggers the search"""
element = self.driver.find_element(*MainPageLocators.SUBMIT_BUTTON)
element.click()
class SearchResultsPage(BasePage):
"""Search results page action methods come here"""
def is_results_found(self):
# Probably should search for this text in the specific page
# element, but as for now it works fine
return "No results found." not in self.driver.page_source
应用实例:一个测试用例
import unittest
from selenium import webdriver
import page
class PythonOrgSearch(unittest.TestCase):
"""A sample test class to show how page object works"""
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.get("http://www.python.org")
def test_search_in_python_org(self):
main_page = page.MainPage(self.driver)
self.assertTrue(main_page.is_title_matches(), "python.org title doesn't match.")
main_page.search_text_element = "pycon"
main_page.click_go_button()
search_results_page = page.SearchResultsPage(self.driver)
self.assertTrue(search_results_page.is_results_found(), "No results found.")
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main()