python+selenium自動化軟體測試(第7章):Page Object模式

來源:互聯網
上載者:User

標籤:es2017   瀏覽器   搜尋   命名   set   複用   而不是   css_   ram   

什麼是Page ObjectModel模式
Page Objects是selenium的一種測試設計模式,主要將每個頁面看作是一個class。class的內容主要包括屬性和方法,屬性不難理解,就是這個頁面中的元素對象,比如輸入使用者名稱的輸入框,輸入登陸密碼的輸入框,登陸按鈕,這個頁面的url等,而方法,主要是指這個頁面可以提供的具體功能。
為什麼選擇POM?
我們先看一段簡單的代碼如下:

from selenium import webdriverimport time driver = webdriver.Firefox()driver.implicitly_wait(30) # 啟動瀏覽器,訪問百度driver.get("http://www.baidu.com") # 定位百度搜尋方塊,並輸入seleniumdriver.find_element_by_id("kw").send_keys("selenium") # 定位百度一下按鈕並單擊進行搜尋driver.find_element_by_id("su").click()time.sleep(5)driver.quit()

這是一個簡單的小指令碼。指令碼維護看起來很簡單。但隨著時間測試套件的增長。隨著你在代碼中添加越來越多的行,事情變得艱難。
指令碼維護的主要問題是,如果10個不同的指令碼使用相同的頁面元素,並且該元素中的任何更改,則需要更改所有10個指令碼。這是耗時且容易出錯的。
更好的指令碼維護方法是建立一個單獨的類檔案,它可以找到Web元素,填充或驗證它們。該類可以在使用該元素的所有指令碼中重用。將來,如果web元素有變化,我們需要在1個類檔案中變更,而不是10個不同的指令碼。
什麼是POM?
頁面物件模型  是 為Web UI元素建立Object Repository的設計模式  。
在這個模型下,對於應用程式中的每個網頁,應該有相應的頁面類。
此Page類將會找到該Web頁面的WebElements,並且還包含對這些WebElements執行操作的頁面方法。
這些方法的名稱應該按照他們正在執行的任務給出,即如果一個載入程式正在等待支付網關出現,POM方法名稱可以是waitForPaymentScreenDisplay()。

為非POM和POM對比圖:

在自動化測試中,引入了Page Object Model(POM):頁面對象模式來解決,POM能讓我們的測試代碼變得可讀性更好,高可維護性,高複用性。
POM的優勢
1.    POM提供了一種在UI層操作、商務程序與驗證分離的模式,這使得測試代碼變得更加清晰和高可讀性。

2.    物件程式庫與用例分離,使得我們更好的複用對象,甚至能與不同的工具進行深度結合應用。

3.    可複用的頁面方法代碼會變得更加最佳化。

4.    更加有效命名方式使得我們更加清晰的知道方法所操作的UI元素。例如我們要回到首頁,方法名命名為: gotoHomePage(),通過方法名即可清晰的知道具體的功能實現。

案例說明:
以下是簡單普通的登入測試案例:

def test_login_mail(self): driver = self.driver driver.get("http://www.xxx.xxx.com") driver.find_element_by_id("idInput").clear() driver.find_element_by_id("xxxxxxx").send_keys("xxxxx") driver.find_element_by_id("xxxxxxx").clear() driver.find_element_by_id("xxxxxxx").send_keys("xxxxxx") driver.find_element_by_id("loginBtn").click()

那我們如何進行一個改造升級呢?
改造案例思路:
第一, 我們要分離測試對象(元素對象)和測試指令碼(用例指令碼),那麼我們分別建立兩個指令檔,分別為: LoginPage.py 用於定義頁面元素對象,每一個元素都封裝成組件(可以看做存放頁面元素對象的倉庫)  CaseLoginTest.py 測試案例指令碼。
第二, 設計實現思想,一切元素和元素的操作組件化定義在Page頁面,用例指令碼頁面,通過調用Page中的組件對象,進行拼湊成一個登入指令檔。

BasePage.py:

#-*- coding: utf-8-*-from selenium.webdriver.support.wait importWebDriverWaitfrom seleniumimport webdriverclassAction(object):""" BasePage封裝所有頁面都公用的方法,例如driver, url ,FindElement等"""#初始化driver、url、等def __init__(self,selenium_driver, base_url, pagetitle):    self.base_url = base_url    self.pagetitle = pagetitle    self.driver = selenium_driver    #開啟頁面,校正頁面連結是否載入正確def _open(self,url, pagetitle):    #使用get開啟訪問連結地址    self.driver.get(url)    self.driver.maximize_window()#使用assert進行校正,開啟的連結地址是否與配置的地址一致。調用on_page()方法    assertself.on_page(pagetitle), u"開啟開頁面失敗 %s"% url #重寫元素定位方法def find_element(self,*loc):    #returnself.driver.find_element(*loc)try:WebDriverWait(self.driver,10).until(lambdadriver: driver.find_element(*loc).is_displayed())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)#定義open方法,調用_open()進行開啟連結def open(self): self._open(self.base_url, self.pagetitle) #使用current_url擷取當前視窗Url地址,進行與配置地址作比較,返回比較結果(True False)def on_page(self,pagetitle):return pagetitlein self.driver.title #定義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)if click_first: self.find_element(*loc).click()if clear_first: self.find_element(*loc).clear() self.find_element(*loc).send_keys(vaule)exceptAttributeError:print u"%s 頁面中未能找到 %s 元素"%(self, loc)

LoginPage.py:

#-*- coding: utf-8-*-from selenium.webdriver.common.by importByimport BasePage#繼承BasePage類class LoginPage(BasePage.Action):#定位器,通過元素屬性定位元素對象 username_loc=(By.ID,"idInput") password_loc =(By.ID,"pwdInput") submit_loc =(By.ID,"loginBtn") span_loc=(By.CSS_SELECTOR,"div.error-tt>p") dynpw_loc =(By.ID,"lbDynPw") userid_loc =(By.ID,"spnUid")#Actiondef open(self):#調用page中的_open開啟串連self._open(self.base_url,self.pagetitle)#調用send_keys對象,輸入使用者名稱def input_username(self, username): self.find_element(*self.username_loc).send_keys(username)#調用send_keys對象,輸入密碼def input_password(self, password): self.find_element(*self.password_loc).send_keys(password)#調用send_keys對象,點擊登入def click_submit(self): self.find_element(*self.submit_loc).click()#使用者名稱或密碼不合理是Tip框內容展示def show_span(self):returnself.find_element(*self.span_loc).text#切換登入模式為動態密碼登入(IE下有效)def swich_DynPw(self): self.find_element(*self.dynpw_loc).click()#登入成功頁面中的使用者ID尋找def show_userid(self):returnself.find_element(*self.userid_loc).text
Caselongintest.py

#-*- coding: utf-8-*-import sysreload(sys)sys.setdef aultencoding(‘utf-8‘)import unittestfrom POimportLoginPagefrom seleniumimport webdriverclassCaselogin126mail(unittest.TestCase):"""登入case """@classmethoddef setUpClass(cls): cls.driver = webdriver.Chrome() cls.driver.implicitly_wait(30)  cls.url ="http://xxxx.xxx.com" cls.username ="xxxxx" cls.password ="xxxxx" #用例執行體def test_login_mail(self):#聲明LoginPage類對象login_page=LoginPage.LoginPage(self.driver, self.url, u”xxxxx”) #調用開啟頁面組件login_page.open()#調用使用者名稱輸入組件login_page.input_username(self.username)#調用密碼輸入組件login_page.input_password(self.password)#調用點擊登入按鈕組件login_page.click_submit()@classmethoddef tearDownClass(cls): cls.driver.quit() if __name__=="__main__": unittest.main()

使用POM進行重新構造代碼結構後,發現代碼測試案例代碼的可讀性提高很多,元素寫成組件的方式,不需要每次都寫findElement直接在指令碼中調用組件就可以使用。
在CaseLoginTest指令碼用例執行體中,一旦我們輸入 login_page並敲入一個點時,LoginPage頁面中的元素對象組件都顯示出來。並且定義好的PageObject組件可以重複在其它的指令碼中進行使用,減少了代碼的工作量,也方便對指令碼進行後期的維護管理,當元素屬性發生變化時,我們只需要對一個PageObaject頁面中的對象組件定義變更即可。
最後做個總結,所有代碼請手動輸入,不要直接拷貝。
再次對POM進行小結:

1.    POM是selenium webdriver自動化測試實踐物件程式庫設計模式
2.    POM使得測試指令碼更易於維護
3.    POM通過物件程式庫方式進一步最佳化了元素、用例、資料的維護組織


python+selenium自動化軟體測試(第7章):Page Object模式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.