最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

不懂PO 設計模式?這篇實戰(zhàn)文帶你搞定 PO

2022-10-11 10:45 作者:愛測軟件測試  | 我要投稿


為UI頁面寫測試用例時(比如web頁面,移動端頁面),測試用例會存在大量元素和操作細節(jié)。當UI變化時,測試用例也要跟著變化, PageObject 很好的解決了這個問題!

使用UI自動化測試工具時(包括selenium,appium等),如果無統(tǒng)一模式進行規(guī)范,隨著用例的增多會變得難以維護,而 PageObject 讓自動化腳本井井有序,將 page 單獨維護并封裝細節(jié),可以使 testcase 更穩(wěn)健,不需要大改大動。

具體做法:把元素信息和操作細節(jié)封裝到Page類中,在測試用例上調用Page對象(PageObject),比如存在一個功能“選取相冊標題”,需要為之建立函數(shù)selectAblumWithTitle(),函數(shù)內(nèi)部是操作細節(jié)findElementsWithClass(‘a(chǎn)lbum’)等:

以選“取相冊標題”舉例,偽代碼如下:

selectAblumWithTitle() { ?

?#選取相冊 ??

?findElementsWithClass('album')?

?? ?#選取相冊標題 ??

?findElementsWithClass('title-field') ??

?#返回標題內(nèi)容 ? ?return getText() }

page object的主要原則是提供一個簡單接口 (或者函數(shù),比如上述的selectAblumWithTitle),讓調用者在頁面上可以做任何操作,點擊頁面元素,在輸入框輸入內(nèi)容等。

因此,如果要訪問一個文本字段,page object應該有獲取和返回字符串的方法。page object應該封裝對數(shù)據(jù)的操作細節(jié),比如查找元素和點擊元素。當頁面元素改動時,應該只改變page類中的內(nèi)容,不需要改變調用它的地方。

不要為每個UI頁面都創(chuàng)建一個page類,應該只為頁面中重要的元素創(chuàng)建page類。

比如,一個頁面顯示多個相冊,應該創(chuàng)建一個相冊列表page object,它包含許多相冊page object。如果某些復雜UI的層次結構只是用來組織UI,那么它就不應該出現(xiàn)在page object中。page object的目的是通過給頁面建模,從而對應用程序的使用者變得有意義:

如果你想導航到另一個頁面,初始page對象應當return另一個page對象,比如點擊注冊,進入注冊頁面,在代碼中就應該return Register()。如果想獲取頁面信息,可以return基本類型(字符串、日期)。

建議不要在page object中放斷言。應該去測page object,而不是讓page object自己測自己,page object的責任是提供頁面的狀態(tài)信息。這里僅用HTML描述Page Object,這種模式還可以用來隱藏Java swing UI細節(jié),它可用于所有UI框架。

PageObject的核心思想是六大原則,掌握六大原則才可以進行 PageObject 實戰(zhàn)演練,這是 PageObject的精髓所在。 selenium官方凝聚出六大原則,后面的PageObject使用都將圍繞六大原則開展:

  • 公共方法代表頁面提供的服務

  • 不要暴露頁面細節(jié)

  • 不要把斷言和操作細節(jié)混用

  • 方法可以return到新打開的頁面

  • 不要把整頁內(nèi)容都放到PO中

  • 相同的行為會產(chǎn)生不同的結果,可以封裝不同結果

下面,對上述六大原則進行解釋:

  • 原則一:要封裝頁面中的功能(或者服務),比如點擊頁面中的元素,可以進入到新的頁面,于是,可以為這個服務封裝方法“進入新頁面”。

  • 原則二:封裝細節(jié),對外只提供方法名(或者接口)。

  • 原則三:封裝的操作細節(jié)中不要使用斷言,把斷言放到單獨的模塊中,比如testcase。

  • 原則四:點擊一個按鈕會開啟新的頁面,可以用return方法表示跳轉,比如return MainPage()表示跳轉到新的PO:MainPage。

  • 原則五:只為頁面中重要的元素進行PO設計,舍棄不重要的內(nèi)容。

  • 原則六:一個動作可能產(chǎn)生不同結果,比如點擊按鈕后,可能點擊成功,也可能點擊失敗,為兩種結果封裝兩個方法,click_success和click_error。

以企業(yè)微信首頁為例,企業(yè)微信首頁有二個主要功能:立即注冊和企業(yè)登錄。

點擊企業(yè)登錄可以進入登錄頁面,在頁面可以掃碼登錄和企業(yè)注冊。

點擊企業(yè)注冊可以進入注冊頁面,在頁面可以輸入相關信息進行注冊。

用page object原則為頁面建模,這里涉及三個頁面:首頁,登錄,注冊。在代碼中創(chuàng)建對應的三個類Index,Login,Register: ? 登陸頁?提供login findPassword功能 – Login類 + login findPassword?法 ? 登錄頁?內(nèi)的元素有多少并不關?,隱藏內(nèi)部界?控件 ? 登錄成功和失敗會分別返回不同的頁? – findPassword – loginSuccess – loginFail ? 通過?法返回值判斷登錄是否符合預期

BasePage是所有page object的父類,它為子類提供公共的方法,比如下面的BasePage提供初始化driver和退出driver,代碼中在base_page模塊的BasePage類中使用__init__初始方法進行初始化操作,包括driver的復用,driver的賦值,全局等待的設置(隱式等待)等等:

from time import sleep

from selenium import webdriver?

from selenium.webdriver.remote.webdriverimport WebDriver

class BasePage: ?

?def __init__(self, driver: WebDriver = None): ??

? ? ?#此處對driver進行復用,如果不存在driver,就構造一個新的 ??

? ? ?if driver is None: ? ??

? ? ?# Index頁面需要用,首次使用時構造新driver? ??

? ? ??self._driver = webdriver.Chrome() ?

? ? ? ? ?# 設置隱式等待時間 ??

? ? ? ? ?self._driver.implicitly_wait(3) ? ??

? ? ? ?# 訪問網(wǎng)頁 ? ? ??

? ? ?self._driver.get(self._base_url) ? ?

?? ?else: ? ? ? ?

? ?# Login與Register等頁面需要用這個方法,避免重復構造driver ? ? ? ? ? ?self._driver = driver ?

??def close(self): ?

? ? ?sleep(20) ? ?

?? ?self._driver.quit()

Index是企業(yè)微信首頁的page object,它存在兩個方法,進入注冊page object和進入登錄page object,這里return方法返回page object實現(xiàn)了頁面跳轉,比如:goto_register方法return Register,實現(xiàn)從首頁跳轉到注冊頁:

class Index(BasePage): ?

?_base_url = "https://work.weixin.qq.com/"?

? ?# 進入注冊頁面 ?

?def goto_register(self): ??

? ? ?self._driver.find_element(By.LINK_TEXT, "立即注冊").click() ??

? ? ?# 創(chuàng)建Register實例后,可調用Register中的方法 ?

? ? ?return Register(self._driver) ??

?# 進入登錄頁面 ??

?def goto_login(self): ? ??

? ?self._driver.find_element(By.LINK_TEXT, "企業(yè)登錄").click() ??

? ? ?# 創(chuàng)建Login實例后,可調用Login中的方法 ?

? ? ?return Login(self._driver)

Login是登錄頁面的page object,主要功能有:進入注冊頁面,掃描二維碼,因此創(chuàng)建兩個方法代表兩個功能:scan_qrcode和goto_registry。代碼跟上面相似,不過多介紹:

from selenium.webdriver.common.by import By?

from test_selenium.page.base_page import BasePage?

from test_selenium.page.register import Register?

class Login(BasePage):?

? ?# 掃描二維碼 ??

?def scan_qrcode(self): ?

??pass ?

?# 進入注冊頁面 ?

??def goto_registry(self): ??

??self._driver.find_element(By.LINK_TEXT, "企業(yè)注冊").click() ? ? ? ?return Register(self._driver)

Register是注冊頁面的page object,主要功能是填寫正確注冊信息,當填寫錯誤時,返回錯誤信息。register方法實現(xiàn)了正確的表格填寫,當填寫完畢時返回自身(頁面還停留在注冊頁)。get_error_message方法實現(xiàn)了錯誤填寫的情況,如果填寫錯誤,就收集錯誤內(nèi)容并返回:

from selenium.webdriver.common.by import By?

from test_selenium.page.base_page import BasePage?

class Register(BasePage): ?

?# 填寫注冊信息,此處只填寫了部分信息,并沒有填寫完全 ??

?def register(self, corpname): ??

? ? ?# 進行表格填寫 ? ?

?? ?self._driver.find_element(By.ID, "corp_name").send_keys(corpname) ? ? ? ?self._driver.find_element(By.ID, "submit_btn").click() ? ??

? ?# 填寫完畢,停留在注冊頁,可繼續(xù)調用Register內(nèi)的方法 ? ??

? ?return self ? ?

#填寫錯誤時,返回錯誤信息 ??

?def get_error_message(self): ? ?

?? ?# 收集錯誤信息并返回 ?

? ? ?result=[] ? ?

?? ?for element in self._driver.find_elements(By.CSS_SELECTOR, ".js_error_msg"): ? ?

??result.append(element.text) ?

??return result

test_index模塊是對上述功能的測試,它獨立于page類,在TestIndex類中只需要調用page類提供的方法即可,比如下面對注冊頁及登陸頁的測試使用了test_register和test_login方法:

from test_selenium.page.index import Index class TestIndex: ?

?# 所有步驟前的初始化 ?

??def setup(self):? ? ??

? self.index = Index() ?

??# 對注冊功能的測試?

?? ?def test_register(self): ?

?? ? ?# 進入index,然后進入注冊頁填寫信息 ? ? ? ?self.index.goto_register().register("霍格沃茲測試學院")?

?? ?# 對login功能的測試 ??

?def test_login(self): ? ? ??

?# 從首頁進入到注冊頁 ? ? ?

??register_page = self.index.goto_login().goto_registry()\ ? ? ? ? ? ?.register("測吧(北京)科技有限公司")? ?

?? ? # 對填寫結果進行斷言,是否填寫成功或者填寫失敗 ??

? ? ?assert "請選擇" in "|".join(register_page.get_error_message())?

?? ?# 關閉driver ??

?def teardown(self): ?

???self.index.close()


不懂PO 設計模式?這篇實戰(zhàn)文帶你搞定 PO的評論 (共 條)

分享到微博請遵守國家法律
临沧市| 双牌县| 象山县| 隆昌县| 安平县| 锡林浩特市| 龙胜| 石屏县| 额尔古纳市| 井研县| 天镇县| 太保市| 双流县| 界首市| 门头沟区| 扎囊县| 蒙阴县| 班戈县| 晋州市| 南靖县| 嵊州市| 上思县| 吉林市| 陵川县| 高平市| 洛川县| 盐山县| 大城县| 柏乡县| 余庆县| 汉沽区| 英超| 松桃| 宜川县| 六盘水市| 神农架林区| 新津县| 江口县| 潼关县| 巴南区| 南华县|