为了解决代码的可重复性和可维护性,对于持续自动化测试很重要的.
开发的信条是: 不做重复的自己, 不写重复的代码
为了解决 上边的问题, Page Object 走上了舞台,跳了一支绚丽的舞蹈.
什么是 Page Object ?
简单的说是 创建对象 对应页面的一个应用.
我们可以把每个页面构建一个类,并且为页面的属性和方法 构建模型.
这就相当于 测试脚本 和 被测的页面 分离一层,屏蔽了定位器,操作方法和业务逻辑.
页面有任何页面元素的改动,并不会影响测试脚本改动.
优点如下:
举例说明如下:
做以下封装 1. browser 2. 封装 page共同的方法 3. page 的定位元素 和操作方法 4. 测试代码
TYPES = {'firefox': webdriver.Firefox, 'chrome': webdriver.Chrome, 'ie': webdriver.Ie, 'phantomjs': webdriver.PhantomJS}
EXECUTABLE_PATH = {'firefox': 'wires', 'chrome': CHROMEDRIVER_PATH, 'ie': IEDRIVER_PATH, 'phantomjs': PHANTOMJSDRIVER_PATH}
class UnSupportBrowserTypeError(Exception):
pass
class Browser(object):
def __init__(self, browser_type='firefox'):
self._type = browser_type.lower()
if self._type in TYPES:
self.browser = TYPES[self._type]
else:
raise UnSupportBrowserTypeError('仅支持%s!' % ', '.join(TYPES.keys()))
self.driver = None
def get(self, url, maximize_window=True, implicitly_wait=30):
self.driver = self.browser(executable_path=EXECUTABLE_PATH[self._type])
self.driver.get(url)
if maximize_window:
self.driver.maximize_window()
self.driver.implicitly_wait(implicitly_wait)
return self
def save_screen_shot(self, name='screen_shot'):
day = time.strftime('%Y%m%d', time.localtime(time.time()))
screenshot_path = REPORT_PATH + '\screenshot_%s' % day
if not os.path.exists(screenshot_path):
os.makedirs(screenshot_path)
tm = time.strftime('%H%M%S', time.localtime(time.time()))
screenshot = self.driver.save_screenshot(screenshot_path + '\\%s_%s.png' % (name, tm))
return screenshot
def close(self):
self.driver.close()
def quit(self):
self.driver.quit()
重写方法如下, find_element , send_keys , switch_to_frame,switch_to_alert,Select()
代码如下;
from selenium.webdriver.support.select import Select
from test_01.common.browser import Browser
class Page(Browser):
# 更多的封装请自己动手...
def __init__(self, page=None, browser_type='chrome'):
if page:
self.driver = page.driver
else:
super(Page, self).__init__(browser_type=browser_type)
def get_driver(self):
return self.driver
def select_dropdownlist(self,*args):
return Select(self.driver.find_element(*args))
def find_element(self, *loc):
# return self.driver.find_element(*loc)
try:
# 确保元素是可见的。
# 注意:以下入参为元组的元素,需要加*。Python存在这种特性,就是将入参放在元组里。
# WebDriverWait(self.driver,10).until(lambda driver: driver.find_element(*loc).is_displayed())
# 注意:以下入参本身是元组,不需要加*
WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(loc))
return self.driver.find_element(*loc)
except:
print
u"%s 页面中未能找到 %s 元素" % (self, loc)
# 重写switch_frame方法
def switch_frame(self, loc):
return self.driver.switch_to_frame(loc)
# 定义script方法,用于执行js脚本,范围执行结果
def script(self, src):
self.driver.execute_script(src)
# 重写定义send_keys方法
def send_keys(self, loc, vaule, clear_first=True, click_first=True):
try:
loc = getattr(self, "_%s" % loc) # getattr相当于实现self.loc
if click_first:
self.find_element(*loc).click()
if clear_first:
self.find_element(*loc).clear()
self.find_element(*loc).send_keys(vaule)
except AttributeError:
print
u"%s 页面中未能找到 %s 元素" % (self, loc)
from selenium.webdriver.common.by import By
from test_01.common.page import Page
class BaiDuMainPage(Page):
loc_search_input = (By.ID, 'kw')
loc_search_button = (By.ID, 'su')
def search(self, kw):
"""搜索功能"""
self.find_element(*self.loc_search_input).send_keys(kw)
self.find_element(*self.loc_search_button).click()
只是 跟page 的方法进行交互, 不同的场景调用不同组合的方法。 跟定位元素完全脱离, 示例代码如下;
这个是我以前的项目的代码
import time
import unittest
from utils.config import Config, DATA_PATH, REPORT_PATH
from utils.log import logger
from utils.file_reader import ExcelReader
from test_01.page.TA.quote_page import Quote_page
from test_01.page.TA.plan_page import Plan_page
from test_01.page.TA.Insured_page import Insured_page
from test_01.page.TA.confirm_pay_page import Comfirm_pay
from test_01.page.TA.pament_page import Payment
from test_01.common.page import Page
class Smoke_TA_Product(unittest.TestCase):
URL = Config().get('URL_TA')
excel = DATA_PATH + '/baidu.xlsx'
page = Quote_page(browser_type='chrome').get(URL, maximize_window=True,implicitly_wait=40)
def sub_tearDown(self):
self.page.quit()
def test_smoke01_quote_page(self):
logger.info("test_quote")
self.page.quote_page()
#执行quote page
def test_smoke02_plan_page(self):
self.page = Plan_page(self.page)
self.page.plan_page()
#执行plan page
def test_smoke03_insured_page(self):
self.page = Insured_page(self.page)
self.page.insured_page()
#执行insured page
def test_smoke04_confirm_pay(self):
self.page=Comfirm_pay(self.page)
self.page.confirm_pay()
#执行 confirm and pay page
def test_smoke04_pay(self):
self.page=Payment(self.page)
self.page.pay()