Page Object設計模式python
Page object是selenium自動化測試項目開發時間的最佳設計模式之一,主要體如今對界面交互細節的封裝。web
1.認識page object
優勢以下:
1.減小代碼的重複
2.提升測試用例的可讀性
3.提升測試用例的可維護性,特別是針對UI頻繁變化的項目。設計模式
2.page object實例
下面以登陸新浪郵箱爲例,經過page object設計模式來實現。瀏覽器
#po_model.py
#coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
class Page(object):
'''基礎類,用於頁面對象類的繼承'''
login_url='https://ui.ptlogin2.qq.com/cgi-bin/login'
def __init__(self,selenium_driver,base_url=login_url):
self.base_url=base_url
self.driver=selenium_driver
self.timeout=30
def on_page(self):
return self.driver.current_url==(self.base_url+self.url)
def _open(self,url):
url=self.base_url+url
self.driver.get(url)
assert self.on_page(),"Did not land on %s" % url
def open(self):
self._open(self.url)
def find_element(self,*loc):
return self.driver.find_element(*loc)
class LoginPage(Page):
'''新浪郵箱登陸頁面模型'''
url='/'
#定位器
username_loc=(By.ID,"u")
password_loc=(By.ID,"p")
submint_loc=(By.ID,"go")
#Action
def type_username(self,username):
self.find_element(*self.username_loc).send_keys(username)
def type_password(self,password):
self.find_element(*self.password_loc).send_keys(password)
def submit(self):
self.find_element(*self.submint_loc).click()
def test_user_login(driver,username,password):
"""測試獲取的用戶名/密碼是否能夠登陸"""
login_page=LoginPage(driver)
login_page.open()
login_page.type_username(username)
login_page.type_password(password)
login_page.submit()
def main():
try:
driver=webdriver.Chrome()
username='xxxxxxxx'
password='xxxxxxxxxx'
test_user_login(driver,username,password)
time.sleep(10)
text=driver.find_element_by_class_name("qm_toolbarTitle").text
assert(text == u'xxxxxxx - 退出'),u"用戶名稱不匹配,登陸失敗!"
finally:
#關閉瀏覽器窗口
driver.close()
if __name__=='__main__':
main()
Page object設計模式的實現方法顯然使結構變得複雜了不少,下面對其逐段分析,來體會這樣設計的好處。函數
1.建立page類測試
class Page(object): '''基礎類,用於頁面對象類的繼承''' login_url='xxxxx' def __init__(self,selenium_driver,base_url=login_url): self.base_url=base_url self.driver=selenium_driver self.timeout=30 def on_page(self): return self.driver.current_url==(self.base_url+self.url) def _open(self,url): url=self.base_url+url self.driver.get(url) assert self.on_page(),"Did not land on %s" % url def open(self): self._open(self.url) def find_element(self,*loc): return self.driver.find_element(*loc)
首先建立一個基礎類Page,在初始化方法__init__()中定義驅動(driver)、基本的URL(base_url)和超時時間(timeout)等。
定義open()方法用於打開URL網站,但它自己並未作這件事情,而是交給_open()方法來實現。關於URL地址的斷言部分,則交給on_page()方法來實現,而find_element()方法用於元素的定位。網站
2.建立LoginPage()類ui
Page類中定義的這些方法都是頁面操做的基本方法,下面根據登陸頁的特色再建立LoginPage類並繼承Page類,這也是Page Object設計模式中最重要的對象層。url
class LoginPage(Page): '''新浪郵箱登陸頁面模型''' url='/' #定位器 username_loc=(By.ID,"u") password_loc=(By.ID,"p") submint_loc=(By.ID,"go") #Action def type_username(self,username): self.find_element(*self.username_loc).send_keys(username) def type_password(self,password): self.find_element(*self.password_loc).send_keys(password) def submit(self): self.find_element(*self.submint_loc).click()
LoginPage類中主要對登陸頁面上的元素進行封裝,使其成爲更具體的操做方法。例如:用戶名、密碼和登陸按鈕都被封裝成了方法。spa
3.建立test_user_login()函數
def test_user_login(driver,username,password): """測試獲取的用戶名/密碼是否能夠登陸""" login_page=LoginPage(driver) login_page.open() login_page.type_username(username) login_page.type_password(password) login_page.submit()
test_user_login()函數將單個的元素操做組成一個完整的動做,而這個動做包含了打開瀏覽器、輸入用戶名/密碼,點擊登陸等單步操做。在使用該函數時須要將driver、username、password等信息做爲函數的入參、這樣該函數具備極強的可重用性。
4.建立main()函數
def main(): try: driver=webdriver.Chrome() username='xxxxx' password='xxxxx' test_user_login(driver,username,password) time.sleep(10) text=driver.find_element_by_class_name("qm_toolbarTitle").text assert(text == u'xxxxx - 退出'),u"用戶名稱不匹配,登陸失敗!" finally: #關閉瀏覽器窗口 driver.close() if __name__=='__main__': main()
main()函數更接近與用戶的操做行爲。對用戶來講,要進行郵箱的登陸,須要關心的就是經過哪一個瀏覽器打開郵箱地址、登陸的用戶名和密碼是什麼,至於輸入框、按鈕是如何定位的,則不須要關心。
這樣分層的好處:不一樣的層關心不一樣的問題,頁面對象層只關心元素的定位問題,測試用例只關心測試的數據。
章小結:介紹了三個知識點:利用HTMLTestRunner生成測試報告、集成自動發郵件功能和page object設計模式,雖然他們之間沒有直接的聯繫,可是合理化的運行到自動化測試項目中將有助於自動化測試項目的開展。