selenium +python之Page Obiect設計模式

來源:互聯網
上載者:User

標籤:click   錯誤資訊   可讀性   編寫   nal   final   log   web頁面   對象   

PageObject是selenium自動化測試專案開發實踐的最佳設計模式之一,它主要體現對介面互動細節的封裝,這樣可以使測試案例更關注於業務而非介面細節,從而提高測試案例的可讀性。

1.認識PageObject

PageObject設計模式的優點如下:

*減少代碼的重複

*提高測試案例的可讀性

*提高測試案例的可維護性,特別針對UI頻繁變動的項目。

當為web頁面編寫測試是,需要操作該web頁面上的元素。然而,如果在測試代碼中直接操作HTML元素,代碼是及其脆弱的,因為ui的變動性會很大。我們可以將page對象封裝成一個HTML頁面,然後通過提供應用程式特定的API來操作頁面元素。而不是在HTML中來定位。

page對象的一個基本經驗法則是:凡是人能夠做的事,page對象通過軟體用戶端都能夠做到。因此,他應該提供一個易於編程的介面並隱藏視窗底層的組件。所以訪問一個文字框應該通過一個存取方法(accessor method)來實現字串的擷取與返回,複選框應當使用布爾值,按鈕應當被表示為行為導向的方法名。page對象應當將在GUI控制項上所有查詢和操作資料的行為封裝為方法

一個好的經驗法則是:即使改變具體的控制項,page對象的介面也不應當發生改變

儘管該術語是:“頁面”對象,但是並不意味著需要針對每個頁面建立一個這樣的對象。例如:頁面有重要意義的元素可以獨立為一個page對象。經驗法則的目的是通過給頁面建模,時期對應用程式的使用者變得更有意義。

 
 1 from selenium import webdriver 2 from selenium.webdriver.common.by import By 3 from time import sleep 4  5  6 class Page(object): 7     """ 8     基礎類,用於頁面對象類的繼承 9     """10     login_url = ‘http://mail.163.com/‘11 12     def __init__(self, selenium_driver, base_url=login_url):13         self.base_url = base_url14         self.driver = selenium_driver15         self.timeout = 3016 17     def on_page(self):18         return self.driver.current_url == (self.base_url + self.url)19 20     def _open(self, url):21         url = self.base_url + url22         self.driver.get(url)23         assert self.on_page(), ‘Did not land on %s‘ % url24 25     def open(self):26         self._open(self.url)27 28     def find_element(self, *loc):29         return self.driver.find_element(*loc)30 31 32 class LoginPage(Page):33     """34     126郵箱登陸頁面模型35     """36     url = ‘/‘37     # 定位器38     username_loc = (By.ID, "idInput")39     password_loc = (By.ID, "pwdInput")40     submit_loc = (By.ID, "loginBtn")41 42     # Action43     def type_username(self, username):44         self.find_element(*self.username_loc).send_keys(username)45 46     def type_password(self, password):47         self.find_element(*self.password_loc).send_keys(password)48 49     def submit(self):50         self.find_element(*self.submit_loc).click()51 52 53 def test_user_login(driver, username, password):54     """55      測試擷取的使用者名稱/密碼是否可以登陸56      """57     login_page = LoginPage(driver)58     login_page.open()59     login_page.type_username(username)60     login_page.type_password(password)61     login_page.submit()62 63 64 def main():65     try:66         driver = webdriver.Chrome()67         username = ‘[email protected]‘68         password = ‘********‘69         test_user_login(driver, username, password)70         sleep(3)71         text = driver.find_element_by_xpath("//span[@id = ‘spnUid‘]").text72         assert (text == ‘[email protected]‘), "使用者名稱稱不匹配,登陸失敗!"73     finally:74         # 關閉瀏覽器視窗75         driver.close()76 77 78 if __name__ == ‘__main__‘:79     main()
 

 代碼解釋如下:

1、建立page類

 
 1 class Page(object): 2     """ 3     基礎類,用於頁面對象類的繼承 4     """ 5     login_url = ‘http://mail.163.com/‘ 6  7     def __init__(self, selenium_driver, base_url=login_url): 8         self.base_url = base_url 9         self.driver = selenium_driver10         self.timeout = 3011 12     def on_page(self):13         return self.driver.current_url == (self.base_url + self.url)14 15     def _open(self, url):16         url = self.base_url + url17         self.driver.get(url)18         assert self.on_page(), ‘Did not land on %s‘ % url19 20     def open(self):21         self._open(self.url)22 23     def find_element(self, *loc):24         return self.driver.find_element(*loc)
首先建立一個基礎類Page,在初始化方法__init__()中定義驅動(driver),基本的URL(base_url)和逾時時間(timeout)等,定義open()方法用於開啟URL網站,但是它本身並未做這件事情,而是交由
_open()方法來實現。關於Url地址的斷言部分,則交由on_page()方法來實現,而find_element()方法用於元素的定位。
 

2.建立LoginPage類

Page類中定義的這些方法都是頁面操作的基本方法。下面根據登陸頁的特點再建立LoginPage類並繼承page類,這也是page object設計模式中最重要的對象層。

 
 1 class LoginPage(Page): 2     """ 3     126郵箱登陸頁面模型 4     """ 5     url = ‘/‘ 6     # 定位器 7     username_loc = (By.ID, "idInput") 8     password_loc = (By.ID, "pwdInput") 9     submit_loc = (By.ID, "loginBtn")10 11     # Action12     def type_username(self, username):13         self.find_element(*self.username_loc).send_keys(username)14 15     def type_password(self, password):16         self.find_element(*self.password_loc).send_keys(password)17 18     def submit(self):19         self.find_element(*self.submit_loc).click()
LoginPage類中主要對登陸頁面上的元素進行封裝,使其成為更具體的操作方法。例如,使用者名稱,密碼和登陸按鈕都被封裝成了方法。
 

3.建立test_user_login()函數

 
1 def test_user_login(driver, username, password):2     """3      測試擷取的使用者名稱/密碼是否可以登陸4      """5     login_page = LoginPage(driver)6     login_page.open()7     login_page.type_username(username)8     login_page.type_password(password)9     login_page.submit()
 

test_user_login()函數將單個的元素操作組成一個完整的動作,而這個動作包含了開啟瀏覽器,輸入使用者名稱/密碼,點擊登陸等單步操作。在使用該函數時需要將driver,username、password等資訊作為函數的入參,這樣該函數具有很強的可重用性。

4.建立main()函數

 
 1 def main(): 2     try: 3         driver = webdriver.Chrome() 4         username = ‘[email protected]‘ 5         password = ‘********‘ 6         test_user_login(driver, username, password) 7         sleep(3) 8         text = driver.find_element_by_xpath("//span[@id = ‘spnUid‘]").text 9         assert (text == ‘[email protected]‘), "使用者名稱稱不匹配,登陸失敗!"10     finally:11         # 關閉瀏覽器視窗12         driver.close()13 14 15 if __name__ == ‘__main__‘:16     main()
 

main()函數更接近於使用者的操作行為,對使用者來說,要進行郵箱登陸,需要關心的就是通過哪個瀏覽器開啟郵箱網址,登陸的使用者名稱和密碼是什麼,至於輸入框,按鈕時如何定位的,則不需要關心。

這樣分層的好處是,不同的層關心不同的問題。頁面對象層只關心元素定位的問題,測試案例只關心測試資料。

一個有分歧的地方是page對象是否應自身包含斷言,或者僅僅提供資料給測試指令碼來設定斷言。在page對象中包含斷言的倡導者認為,這又助於避免在測試指令碼中出現重複的斷言,可以更容易的提供更好的錯誤資訊,並且提供更接近只做不問風格的API。不在page對象中包含斷言的倡導者認為,包含斷言會混合訪問頁面資料和實現斷言邏輯的職責,並且導致page對象過於臃腫。

在page對象中不包含斷言,雖然我們可以通過為常用的斷言提供斷言庫的方式來消除重複,提供更好的診斷,但從使用者的角度去自動化的觀點來看,判斷是否登陸成功是使用者需要做的事情,不該交由頁面對象層來完成。

使用page object模式之後的另外一個好處就是有助於降低冗餘。如果需要在10個用例中輸入不同的使用者名稱/密碼登陸,那麼main()方法竟會變得非常簡潔。

selenium +python之Page Obiect設計模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.