前言
bok choy是一個開源的使用python語言媳荒,以Page Object模式封裝selenium的驗收測試框架鸟顺。在工作中可以用它來做UI層面的自動化族铆。為了更好地理解本文叶堆,您需要有selenium和python的基礎(chǔ)知識包斑。
準備工作
需要安裝python和pip
使用pip安裝即可干旧。
pip install bok_choy
寫Page
PO設(shè)計模式中是以頁面(page)為一個單位渠欺,作為一個對象。將這個頁面所做的動作作為這個頁面對象的方法(比如點擊某個按鈕椎眯,在某個輸入框輸入文字等操作)挠将,在具體寫用例的時候都是實例化頁面對象,調(diào)用該對象的相應(yīng)方法编整,這樣寫的好處是:如果某個頁面進行了改版舔稀,頁面元素發(fā)生了改變,對測試用例是沒有影響的掌测,只要在相應(yīng)的Page object里修改相應(yīng)方法就好了内贮。
寫Pages前需要分析測試場景,以測試百度搜索為例汞斧,首先需要在百度搜索頁面輸入關(guān)鍵字夜郁,并點擊搜索按鈕。然后頁面會跳轉(zhuǎn)到一個搜索結(jié)果頁粘勒,我們驗證結(jié)果頁是否包含關(guān)鍵字即可竞端。在這個場景中,我們涉及到了兩個頁面庙睡,一個是搜索首頁事富,一個是搜索結(jié)果頁,我們新建一個pages.py文件乘陪,見下面的代碼赵颅。
# -*- coding: utf-8 -*-
from bok_choy.page_object import PageObject
class BaiduSearchPage(PageObject):
"""
Baidu search page
"""
url = 'https://www.baidu.com/'
def is_browser_on_page(self):
return self.q(css='#su').is_present()
def input_search_key(self, keyword):
return self.q(css="#kw").fill(keyword)
def click_search_btn(self):
self.q(css="#su").click()
def search(self, keyword):
self.input_search_key(keyword)
self.click_search_btn()
BaiduSearchResultPage(self.browser).wait_for_page()
class BaiduSearchResultPage(PageObject):
"""
Baidu search result page
"""
url = None
def is_browser_on_page(self):
return self.q(css='h3').is_present()
@property
def search_results(self):
return self.q(css='h3').first.text
如上述代碼所示,自己寫的頁面對象都繼承于bokchoy的PageObject暂刘,每個頁面對象都必須給url賦值饺谬,還要實現(xiàn)is_browser_on_page方法。
url是這個頁面的入口谣拣,在測試過程中募寨,會遇到一種情況是你不關(guān)心它的url具體是多少,因為這個頁面總是從別的頁面點擊進入的森缠,而不是直接從瀏覽器輸入url進入拔鹰,這時,將它的url設(shè)為None即可,上例中的BaiduSearchResultPage(搜索結(jié)果頁)就是這種情況贵涵。
is_browser_on_page方法列肢,是PageObject類的抽象方法恰画,需要在子類中具體實現(xiàn)。這個方法的作用主要是判斷瀏覽器打開的是不是你要的這個頁面瓷马。在百度搜索頁這個實例中拴还,為了確保搜索首頁打開并加載完成了,我用了搜索按鈕是否存在來判斷欧聘。而對于搜索結(jié)果頁片林,必須有測試結(jié)果在頁面展示出來,才能說明這個頁面完全打開了怀骤,所以用測試結(jié)果元素是否存在來判斷费封。
bok-choy中提供兩種定位方式:css和xpath,本例中使用css定位蒋伦。
self.q(css='#su')
除了url和is_browser_on_page是每個頁面對象都有的弓摘,其他方法需要根據(jù)具體頁面上的元素和操作來增加。
BaiduSearchPage-百度搜索首頁痕届,在這個頁面我們需要做的操作有1.在輸入框輸入文字韧献,所以我們寫了input_search_key方法;2.點擊搜索按鈕爷抓,所以我們寫了click_search_btn方法势决,從方法的命名上我們也能看出來這兩個方法是什么作用阻塑。一個完整的搜索動作蓝撇,包含了這兩個步驟,所以又寫了一個search方法陈莽。頁面中的各種操作方法相當于一塊一塊的拼圖渤昌,具體想拼成什么樣,根據(jù)不同測試場景可以自由地組合走搁。目前頁面中的search方法算是兩個小拼圖拼出的一個場景独柑。在百度的首頁,還可以點擊貼吧私植、圖片等忌栅,這些操作也可以寫到這個頁面對象中,以備其他測試場景使用曲稼。
BaiduSearchResultPage-搜索結(jié)果頁索绪,這個頁面是在搜索頁點搜索按鈕之后,跳轉(zhuǎn)進入的贫悄。進入這個頁面后瑞驱,主要是需要驗證搜索結(jié)果中包含搜索關(guān)鍵字。因而有了search_results來返回搜索第一個結(jié)果的文字窄坦,以便于在測試中去使用唤反。這個方法加了property裝飾器凳寺,區(qū)別將在下一部分展示。
寫測試用例
有了pages.py之后彤侍,就可以寫用例啦,建立test_search.py文件肠缨。
# -*- coding: utf-8 -*-
import os
import unittest
from bok_choy.web_app_test import WebAppTest
from pages import BaiduSearchPage, BaiduSearchResultPage
class TestBaidu(WebAppTest):
"""
Tests for the Baidu site.
"""
def setUp(self):
"""
Instantiate the page object.
"""
super(TestBaidu, self).setUp()
self.baidu_search_page = BaiduSearchPage(self.browser)
def test_page_existence(self):
"""
Make sure that the page is accessible.
"""
self.baidu_search_page.visit()
def test_search(self):
test_key = u"學堂在線"
self.baidu_search_page.visit().search(test_key)
self.baidu_results_page = BaiduSearchResultPage(self.browser)
result = self.baidu_results_page.search_results
assert test_key in result[0]
if __name__ == '__main__':
os.environ["SELENIUM_BROWSER"] = "chrome"
unittest.main()
bok-choy默認是使用firefox運行測試用例,它支持的瀏覽器有火狐拥刻、chrome怜瞒、IE、safari和phantomjs般哼。如果想要修改運行測試的瀏覽器吴汪,需要修改一下環(huán)境變量SELENIUM_BROWSER即可。本例中蒸眠,我們將運行測試的瀏覽器換成了chrome漾橙。其他有效值有'firefox', 'internet explorer'楞卡, 'safari'和 'phantomjs'霜运,使用非火狐瀏覽器記得下載相應(yīng)的Webdriver,將webdriver放到與測試相同的文件夾下即可蒋腮。
在測試文件中淘捡,首先需要實例化頁面對象
self.baidu_search_page = BaiduSearchPage(self.browser)
然后就可以調(diào)用該頁面對象的方法
self.baidu_search_page.visit().search(test_key)
請注意,在調(diào)用操作方法的時候先調(diào)用了visit()池摧,visit方法通過在頁面對象中定義的url打開頁面焦除。在頁面中做的任何操作,前提都是該頁面被正確地打開了作彤,所以每次調(diào)用都應(yīng)該先調(diào)visit()膘魄。
但是,我們注意到在取搜索結(jié)果的時候并沒有調(diào)用visit竭讳,代碼如下:
self.baidu_results_page.search_results
這是因為在寫search_results時创葡,我們加上了裝飾器property,那它就變成對象的屬性了绢慢,可以直接用“點”訪問到灿渴。
最后我們用assert 對測試結(jié)果進行驗證。
運行測試
代碼已寫完胰舆,現(xiàn)在可以跑測試(≧≦)/啦骚露! 運行結(jié)果如下。
在測試的過程中思瘟,如果測試用例沒有pass荸百,框架會自動默認在跑測試的路徑下保存截圖和日志,如果你想把他們保存在別的地方滨攻,可修改環(huán)境變量SCREENSHOT_DIR和SELENIUM_DRIVER_LOG_DIR够话。
bok-choy的基本使用就是如此蓝翰,你學會了嗎?想了解更多可訪問官方文檔(見參考文獻)哦~
以上示例代碼可在github查看