6.页面对象
本章是页面对象设计模式的教程介绍。页面对象表示测试正在进行交互的Web应用程序用户界面中的区域。
使用页面对象模式的好处:
- 创建可在多个测试用例之间共享的可重用代码
- 减少重复代码的数量
- 如果用户界面发生更改,则修复程序只需要在一个位置进行更改
6.1。测试用例
这是一个测试用例,它在python.org网站上搜索一个单词并确保找到一些结果。
import unittest
from selenium import webdriver
import page
class PythonOrgSearch(unittest.TestCase):
"""演示页面对象如何工作的示例测试类"""
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.get("http://www.python.org")
def test_search_in_python_org(self):
"""
测试python.org的搜索功能。搜索单词“pycon”,然后验证出现了一些结果。
注意,它不会在搜索结果页面中寻找任何特定的文本。这个测试验证了这一点
结果并不是空的。
"""
#加载主页。这里是Python.org的主页。
main_page = page.MainPage(self.driver)
#检查单词“Python”是否在标题中
assert main_page.is_title_matches(), "python.org title doesn't match."
#将搜索文本框的文本设置为“pycon”
main_page.search_text_element = "pycon"
main_page.click_go_button()
search_results_page = page.SearchResultsPage(self.driver)
#验证结果页是否为空
assert search_results_page.is_results_found(), "No results found."
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main()
6.2。页面对象类
页面对象模式旨在为每个网页创建一个对象。通过遵循该技术,创建了测试代码和技术实现之间的一层分离。
该page.py
会是这样的:
from element import BasePageElement
from locators import MainPageLocators
class SearchTextElement(BasePageElement):
"""该类从指定的定位器获取搜索文本"""
#The locator for search box where search string is entered
locator = 'q'
class BasePage(object):
"""基类来初始化将从所有页中调用的基页"""
def __init__(self, driver):
self.driver = driver
class MainPage(BasePage):
"""主页操作方法在这里。例如Python.org"""
#声明一个变量,该变量将包含检索到的文本
search_text_element = SearchTextElement()
def is_title_matches(self):
"""验证硬编码文本“Python”出现在页面标题中"""
return "Python" in self.driver.title
def click_go_button(self):
"""触发搜索"""
element = self.driver.find_element(*MainPageLocators.GO_BUTTON)
element.click()
class SearchResultsPage(BasePage):
"""搜索结果页面的操作方法在这里"""
def is_results_found(self):
# 也许应该在特定的页面中搜索这个文本
# 元素,但目前运行良好
return "No results found." not in self.driver.page_source
6.3。页面元素
该element.py
会是这样的:
from selenium.webdriver.support.ui import WebDriverWait
class BasePageElement(object):
"""在每个页对象类上初始化的基页类。"""
def __set__(self, obj, value):
"""将文本设置为提供的值"""
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):
"""获取指定对象的文本"""
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")
6.4。定位器
其中一种做法是将定位器字符串与它们被使用的位置分开。在此示例中,同一页面的定位器属于同一个类。
该locators.py
会是这样的:
from selenium.webdriver.common.by import By
class MainPageLocators(object):
"""用于主页定位器的类。所有主页定位器都应该在这里"""
GO_BUTTON = (By.ID, 'submit')
class SearchResultsPageLocators(object):
"""用于搜索结果定位器的类。所有的搜索结果定位器都应该在这里"""
pass