page object 是一種分層的思想,用戶並不關心是如何找到元素的,用戶只是進行輸入,提交這些操做而已,如何讓代碼進行合理的分層,使得更加接近用戶的行爲,而隱藏掉一些定位的細節,更參數化,使得代碼複用性更高,提升測試用例的可讀性以及用例的可維護性python
當web頁面編寫測試用例時,須要操做web頁面上的元素,然而若是在測試代碼中直接操做HTML元素,那麼這個代碼是很是脆弱的,UI是常常變更的,用page對象封裝成一個HTML頁面,裏面包含定位元素,並封裝成接口提供給測試用例進行調用,這樣在最終的測試用例中無需在HTML中尋找,只是調用接口而已,一旦變更,測試用例的邏輯是不變的,調用的函數仍是那個,只是那個函數定位的元素變了而已web
不是page_object模式把定位元素和測試方法按照過程式的寫下來,而page_object設計過的代碼則是把定位元素與測試方法分離,用戶關心的是classB,而classA對於用戶是黑盒的,但它給classB提供接口app
page並不必定是一個頁面,更加合理的解釋是經過給「頁面」建模,使其對測試方法變得更有意義,如登陸框須要輸入用戶名和密碼和登陸操做ide
non_page_object函數
driver.find_element_by_name("uid") driver.find_element_by_name("password") driver.find_element_by_name("submit").click()
page_object測試
import login_page def test_login(username, password): login_page.SetUsername(username) login_page.SetPassword(password) login_page.Submit()
test_login就是接口提供給測試用例調用的接口,能夠更改 username,password進行關鍵字驅動,頁面對象層只關心元素定位的問題,測試用例只關心測試的數據,如username,password經過這樣的設計,若是webUI中的登陸locator變了,咱們只須要改動login_page,而對於測試用例則不變,不管UI如何變化,登陸的流程是不會變的,輸入用戶名,密碼,提交,這就是分層ui
下面介紹一個實例來講明page_object的設計設計
打開網頁 http://demo/guru99.com/v4/ 獲取網頁title, 判斷是否在一個登陸頁面上 輸入用戶名 輸入密碼 登陸 獲取網頁中的一個登陸成功的元素中的文本,驗證是否登陸成功
non_page_object_logincode
#!/usr/bin/env python from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait driver = webdriver.Firefox() driver.implicitly_wait(10) #open page driver.get("http://demo.guru99.com/v4/") #find check point about login_page homeText = driver.find_element_by_xpath("//div[1]/h2").text #judge client open login_page successful assert homeText == "Guru99 Bank", 'cannot go to login page' #set username driver.find_element_by_name("uid").send_keys("mngr44067") #set password driver.find_element_by_name("password").send_keys("etUtamE") #submit driver.find_element_by_name("btnLogin").click() #get text about valid user info hometext = driver.find_element_by_xpath("//table[1]/tbody/tr[3]/td").text #judge user login successful assert hometext == "Manger Id : mngr44067", "invalid user" #invalid user and pop alert to accept try: driver.switch_to_alert().accept() except: pass #verify go back to home page assert homeText == "Guru99 Bank", "no found" driver.close()
紅色標出來的就是檢查點,這個代碼是很是脆弱的,若是換一個用戶名,就要重寫,若是webUI變更一下,這個代碼就要修改對象
page_object分離webElement,test_case,根據頁面進行分離,首先是登陸頁面,以後是成功登陸後的頁面,分別定義,最後再根據用戶思想進行測試用例編寫
page_login.py
#!/usr/bin/env python from selenium import webdriver from selenium.webdriver.common.by import By class Guru99Login(object): #Locator user = (By.NAME, "uid") password = (By.NAME,"password") homeText = (By.XPATH,"//div[1]/h2") submit = (By.NAME,"btnLogin") #Action def __init__(self,driver): self.driver = driver def SetUsername(self, name): self.driver.find_element(*self.user).send_keys(name) def SetPassword(self,password): self.driver.find_element(*self.password).send_keys(password) def ClickLogin(self): self.driver.find_element(*self.submit).click() def GetLoginTitle(self): return self.driver.find_element(*self.homeText).text #Interface def TestLogin(self, username, password): self.SetUsername(username) self.SetPassword(password) self.ClickLogin()
該文件最主要的是TestLogin函數,把測試用到的數據參數化,提供給測試用例,而以前的Action是對TestLogin的進一步分層,單位動做
page_home.py
#!/usr/bin/env python from selenium import webdriver from selenium.webdriver.common.by import By class Guru99HomePage(object): HomeText_loc = (By.XPATH,"//table[1]/tbody/tr[3]/td") def __init__(self,driver): self.driver = driver def GetHomePageUserName(self): return self.driver.find_element(*self.HomeText_loc).text
該文件是成登陸成功判斷用的,因爲在另外一個頁面,咱們也把它做爲page對象封裝起來,它的接口就是GetHomePageUserName()
pom_testcase.py
#!/usr/bin/env python from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By import unittest, time, re import page_home import page_login class Test_Login(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.driver.implicitly_wait(10) self.driver.get("http://demo.guru99.com/v4/") def test_home_page_appear(self): objLogin = page_login.Guru99Login(self.driver) loginTitle = objLogin.GetLoginTitle() assert loginTitle == "Guru99 Bank", "title is wrong" objLogin.TestLogin("mngr44067","etUtamE") objHomePage = page_home.Guru99HomePage(self.driver) assert objHomePage.GetHomePageUserName() == "Manger Id : mngr44067", "invalid user" def tearDown(self): self.driver.close() if __name__ == '__main__': unittest.main()
測試用例用unittest
測試方法 test_home_page_appear() 判斷title 登陸 判斷登陸成功
不管UI如何變,該測試用例無需修改,只須要修改page_login, page_home就好了,代碼可用性很高,只須要改用戶名,密碼就能進行測試
參考:
www.guru99.com <selenium2 自動化測度實戰> selenium guide