網站自動化測試程式如何將測試邏輯與網頁元件分離 (Page Object)?
這篇文章主要說明如何將網頁畫面的修改與程式測試的邏輯分離,
網頁測試程式主要由兩部分組成。一部分是網頁的位置與資訊。例如:按鈕的位子、文字框的值等。
另外一部份就是測試的邏輯。例如:點選畫面的步驟、驗證預期與實際結果等。
將這兩部分分離的目的是希望當畫面有修改的時候,我們只要針對畫面微調的部分修改,不需要修改測試邏輯。
同樣的,當測試邏輯需要調整的時候,只需要針對測試邏輯修改。
將網頁網化的操作與測試邏輯程式分離,這樣的設計方式就稱為 Page Object.
文章最後,我們舉 Google Search 為例子說明如何實作 Page Object與 Page Object的好處。
什麼是 Page Object
Page Object 簡單來說就是描述特定網頁頁面資訊的物件。
舉例來說,我們可以描述網頁下列資訊
- 網頁的 Page Title
- 網頁特定元件的值。例如 Button or Text 的值
我們也可以定義需要執行的 function,例如
- 瀏覽指定網址
- 鍵盤輸入指定關鍵字
定義 Page Object 的目的就是要跟測試邏輯分開。
只要跟畫面有關的修改就更動 Page Object
其他所有測試的邏輯或是測試個案都可以共用這個 Page Object。
Google Page 的 Page Object
舉Google Search Page 為例子。針對這個頁面,可以定義一些屬性與 function 供未來其他測試個案與測試程式使用。
- 定義 is_loaded 看看Google的首頁是否有正常被載入
-
定義Google_searchButton_xpath,之後其他測試程式如果需要 Search Button Xpath 就可以使用。
未來如果 Xpath 有改變只需要修改 Page Object就好。
-
定義google_button_vale,取得Google Button 上顯示的值
- 定義SearchKeyword的功能,只需要將搜尋關鍵字用參數帶入 SearchKeyword就可以對Google Search
[pastacode lang=”python” message=”” highlight=”” provider=”manual”]
class test_Google_pageObject(object):
def __init__(self, driver):
self._driver = driver
self._url = "http://www.google.com/"
self._title = "Google"
@property
def Google_searchButton_xpath(self):
return "//*[name='btnK']"
@property
def is_loaded(self):
return self._driver.title == self._title
@property
def google_button_vale(self):
google_button = self._driver.find_element_by_name('btnK')
return google_button.get_attribute('value')
def open(self):
self._driver.get(self._url)
def SearchKeyword(self,mykeyword):
Search_field = self._driver.find_element_by_name('q')
Search_field.clear()
Search_field.send_keys(mykeyword)
def close(self):
self._driver.close()
[/pastacode]
定義好 Page Object 之後如何使用呢?
範例程式如下:
[pastacode lang=”python” message=”” highlight=”” provider=”manual”]
import unittest
from selenium.webdriver.firefox.webdriver import WebDriver
from test_Google_pageObject import test_Google_pageObject
class test_Google_use_pageObject(unittest.TestCase):
def test_Google(self):
driver = WebDriver()
testGoogle = test_Google_pageObject(driver)
testGoogle.open()
print "Google page is loaded? " + str(testGoogle.is_loaded)
print "Google button value = " + testGoogle.google_button_vale
testGoogle.SearchKeyword("page object")
print "predefined button xpath =" + testGoogle.Google_searchButton_xpath
if __name__ == '__main__':
unittest.main()
[/pastacode]
當然如果只有一個測試程式會使用到 GooglePage Object程式會變得有些繁瑣
但是如果測試程式有很多的情況下,這些所有測試程式都可以共用這個Google Page Object,
未來就算 Google Page 有修改的情況下,也只需要修改 Google Page Object 的網頁屬性,
整個程式在維護與大量測試個案的情況下就變得很方便。
如果不使用 Page Object 的話,筆者建議至少把網頁元件的 Xpath 集中定義在一個地方。
這樣至少網頁元件有改的時候,可以很快的找到。而不會散布在程式各個地方。造成維護上的困難。