Python Selenium設計模式-POM

前言

本文就python selenium自動化測試實踐中所需要的POM設計模式進行分享,以便大家在實踐中對POM的特點、應用場景和核心思想有一定的理解和掌握。

為什麼要用POM

基於python selenium2開始UI級自動化測試並不是多麼艱巨的任務。只需要定位到元素,執行對應的操作即可。下面我們看一下這個簡單的腳本實現百度搜索。

from selenium import webdriverimport timedriver = 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個頁面,100個頁面,甚至1000個呢?那頁面元素的任何改變都會讓我們的腳本維護變得繁瑣複雜,而且變得耗時易出錯。

那怎麼解決呢?

在自動化測試中,引入了Page Object Model(POM):頁面對象模式來解決,POM能讓我們的測試代碼變得可讀性更好,高可維護性,高復用性。

下圖為非POM和POM對比圖:

pom.png

POM是什麼

  • 頁面對象模型(POM)是一種設計模式,用來管理維護一組web元素集的對象庫
  • 在POM下,應用程序的每一個頁面都有一個對應的page class
  • 每一個page class維護著該web頁的元素集和操作這些元素的方法
  • page class中的方法命名最好根據其對應的業務場景進行,例如通常登錄後我們需要等待幾秒中,我們可以這樣命名該方法: waitingForLoginSuccess().

下面我們看看POM的代碼目錄組織示例:

pages_dir.png

POM的優勢

  1. POM提供了一種在UI層操作、業務流程與驗證分離的模式,這使得測試代碼變得更加清晰和高可讀性
  2. 對象庫與用例分離,使得我們更好的復用對象,甚至能與不同的工具進行深度結合應用
  3. 可復用的頁面方法代碼會變得更加優化
  4. 更加有效的命名方式使得我們更加清晰的知道方法所操作的UI元素。例如我們要回到首頁,方法名命名為: gotoHomePage(),通過方法名即可清晰的知道具體的功能實現。

    POM實現示例

    下面我們看下使用POM百度搜索 POM代碼示例:

    看先下代碼組織結構如下:

    page_demo_dir.png

# basePage.py代碼如下# _*_ coding:utf-8 _*___author__ = 苦葉子import sysreload(sys)sys.setdefaultencoding("utf-8")# pages基類class Page(object): """ Page基類,所有page都應該繼承該類 """ def __init__(self, driver, base_url=u"http://www.baidu.com"): self.driver = driver self.base_url = base_url self.timeout = 30 def find_element(self, *loc): return self.driver.find_element(*loc) def input_text(self, loc, text): self.find_element(*loc).send_keys(text) def click(self, loc): self.find_element(*loc).click() def get_title(self): return self.driver.title

# searchPage.py 代碼如下# _*_ coding:utf-8 _*___author__ = 苦葉子import sysfrom selenium.webdriver.common.by import Byfrom pages.basePage import Pagereload(sys)sys.setdefaultencoding("utf-8")# 百度搜索pageclass SearchPage(Page): # 元素集 # 搜索輸入框 search_input = (By.ID, ukw) # 百度一下 按鈕 search_button = (By.ID, usu) def __init__(self, driver, base_url=u"http://www.baidu.com"): Page.__init__(self, driver, base_url) def gotoBaiduHomePage(self): print u"打開首頁: ", self.base_url self.driver.get(self.base_url) def input_search_text(self, text=u"開源優測"): print u"輸入搜索關鍵字: 開源優測 " self.input_text(self.search_input, text) def click_search_btn(self): print u"點擊 百度一下 按鈕" self.click(self.search_button)

# testSearchPage.py代碼如下# _*_ coding:utf-8 _*___author__ = 苦葉子import unittestimport sysfrom selenium import webdriverfrom pages.searchPage import SearchPagereload(sys)sys.setdefaultencoding("utf-8")# 百度搜索測試class TestSearchPage(unittest.TestCase): def setUp(self): self.driver = webdriver.Ie() def testSearch(self): driver = self.driver # 百度網址 url = u"http://www.baidu.com" # 搜索文本 text = u"開源優測" # 期望驗證的標題 assert_title = u"開源優測_百度搜索" print assert_title search_Page = SearchPage(driver, url) # 啟動瀏覽器,訪問百度首頁 search_Page.gotoBaiduHomePage() # 輸入 搜索詞 search_Page.input_search_text(text) # 單擊 百度一下 按鈕進行搜索 search_Page.click_search_btn() # 驗證標題 self.assertEqual(search_Page.get_title(), assert_title) def tearDown(self): self.driver.quit()

# 主入口程序代碼如下# _*_ coding:utf-8 _*___author__ = 苦葉子import unittestimport sysfrom common import HTMLTestRunnerfrom testcase.testSearchPage import TestSearchPagereload(sys)sys.setdefaultencoding("utf-8")if __name__ == __main__: testunit = unittest.TestSuite() testunit.addTest(TestSearchPage(testSearch)) # 定義報告輸出路徑 htmlPath = u"page_demo_Report.html" fp = file(htmlPath, "wb") runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title=u"百度測試", description=u"測試用例結果") runner.run(testunit) fp.close()

按照如圖所示組織代碼結構,輸入如上代碼,執行以下命令運行,會在當前目錄生成測試報告:

python main.py

總結

最後做個總結,所有代碼請手動輸入,不要直接拷貝。再次對POM進行小結

  1. POM是selenium webdriver自動化測試實踐對象庫設計模式
  2. POM使得測試腳本更易於維護
  3. POM通過對象庫方式進一步優化了元素、用例、數據的維護組織

推薦閱讀:

python selenium2自動化測試系列電子書
在Selenium Webdriver中使用XPath Contains、Sibling函數定位

TAG:Selenium | 自動化測試 | 軟體測試 |