您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“Python中PO模式如何設(shè)計(jì)與實(shí)現(xiàn)”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Python中PO模式如何設(shè)計(jì)與實(shí)現(xiàn)”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識(shí)吧。
一種在測(cè)試自動(dòng)化中變得流行的設(shè)計(jì)模式,使得自動(dòng)化測(cè)試腳本的代碼量減少,避免代碼重復(fù),更加易讀,減少維護(hù)的成本。
其實(shí)簡(jiǎn)單來說就是將頁面的操作、腳本的Case、通用的頁面元素分開的這樣一個(gè)模式。
一般 PO 設(shè)計(jì)模式多數(shù)分為三層
第一層:(核心、BasePage層)
對(duì) Selenium 的底層進(jìn)行二次封裝,定義一個(gè)所有頁面都繼承的基礎(chǔ)屬性頁面 —> BasePage 。
封裝 Selenium 的基本方法,例如:元素定位、元素等待、導(dǎo)航頁面、頁面跳轉(zhuǎn)等等...
PS:其實(shí)在使用的過程中不需要全部封裝,用到多少方法就封裝多少方法即可。(之前接觸過其他大佬的自動(dòng)化框架,他把所有的 selenium 的底層的方法做了一層封裝,這樣做很好,能夠做很多的事情,但是比較繁重。實(shí)際上在真實(shí)使用的時(shí)候用不到那么多,所以不建議全部封裝)。
第二層:(頁面層、也叫配置層)
頁面元素進(jìn)行分離,每個(gè)元素只定位一次,隔離定位。如果頁面改變,只需要改變相應(yīng)的元素定位。
如果存在一些業(yè)務(wù)的屬性、方法,需要將其通過業(yè)務(wù)方法的方式將業(yè)務(wù)與操作元素的動(dòng)作分離開來。
第三層:(封裝測(cè)試層)
使用單元測(cè)試框架對(duì)業(yè)務(wù)邏輯進(jìn)行封裝測(cè)試
UI 頁面的頻繁變化,導(dǎo)致頁面 UI 元素頻繁的變動(dòng),PO設(shè)計(jì)模式便于元素定位改變的維護(hù)。
傳統(tǒng)線性自動(dòng)化,多個(gè)用例腳本中需要反復(fù)的定位同一個(gè)元素,PO設(shè)計(jì)模式可以減少這部分頻繁定位元素的代碼量
小節(jié):減少重復(fù)代碼的冗余,便于UI頁面頻繁變更下的元素定位維護(hù)。
首先在項(xiàng)目里創(chuàng)建一個(gè) python package 命名為 pages ,然后在 pages 創(chuàng)建一個(gè)模塊 base_page.py 用來作為第一層的 base_page核心層 。
如下圖:
嘗試構(gòu)建最基礎(chǔ)的 base_page 層,代碼示例如下:
# coding:utf-8 from selenium import webdriver class BasePage(object): """ 1、第一層 - 核心層-BasePage層,定義一個(gè)所有頁面都繼承的page層 2、對(duì)將要使用的 selenium 的底層方法進(jìn)行二次封裝 """ def __init__(self, driver, path=None): # 構(gòu)造函數(shù),類的初始化 """ 為了方便編寫將 driver 初始化, 先使用 "self.driver = webdriver.Chrome()" 后續(xù)改為 self.driver = driver """ self.driver = webdriver.Chrome() # self.driver = driver self.driver.implicitly_wait(5) # 定義全局的默認(rèn)加載時(shí)間 self.load_page(path) # 訪問并加載網(wǎng)頁 def load_page(self, path=None): # 訪問并加載網(wǎng)頁,如果 path 不為空的話,直接傳給 driver.get() 訪問 if path is not None: self.driver.get(path) def by_xpath(self, xpath): # 二次封裝 selenium 的 xpath 元素定位 return self.driver.find_element_by_xpath(xpath) def js_click(self, xpath): # JavaScript 定位元素,并執(zhí)行 click self.driver.execute_script('arguments[0].click()', self.by_xpath(xpath))
到這里,base_page 層算是寫完了,這就是一個(gè)最底層、最基礎(chǔ)的類,這個(gè)類讓我們實(shí)現(xiàn)了 selenium 底層的 Xpath 定位方法 與 JavaScript 定位元素方法,這些方法能夠幫助我們更好的去完成后續(xù)的定位處理操作。
ok,接下我們?cè)偃ゾ帉懜鱾€(gè)頁面層的東西。
代碼示例如下:
# coding:utf-8 from selenium import webdriver from pages.base_page import BasePage # 導(dǎo)入 base_page 層 class HomePage(BasePage): # 定義 FirstPage(繼承 BasePage ) """ 1、第二層 - 各個(gè)頁面單獨(dú)封裝成層,頁面的元素、操作、流程 """ def direct_to_login(self): # 首頁跳轉(zhuǎn)至登錄頁 return self.by_xpath("//*[@id='app']/div[1]/div[5]/div[3]") def direct_to_product(self): # 登陸成功后,跳轉(zhuǎn)至首頁 return self.by_xpath("//*[@id='app']/div[1]/div[5]/div[1]") # 方法流程 def cross_to_login(self): self.direct_to_login().click() # 點(diǎn)擊 "登錄" 按鈕進(jìn)行登錄 def cross_to_product(self): self.direct_to_product().click() # 點(diǎn)擊 "首頁" 跳轉(zhuǎn)至首頁
代碼示例如下:
# coding:utf-8 from selenium import webdriver from pages.base_page import BasePage # 導(dǎo)入 base_page 層 class LoginPage(BasePage): # 定義 FirstPage(繼承 BasePage ) """ 1、頁面層(登錄頁) - 各個(gè)頁面單獨(dú)封裝成層,頁面的元素、操作、流程 """ def login_username(self): # 登錄頁 - 用戶名輸入框 return self.by_xpath("//*[@id='app']/div[1]/form/div[1]/div[2]/div/input") def login_password(self): # 登錄頁 - 密碼輸入框 return self.by_xpath("//*[@id='app']/div[1]/form/div[2]/div[2]/div/input") def login_button(self): # 登錄頁 - 登錄按鈕 return self.by_xpath("//*[@id='app']/div[1]/form/div[3]/button") # 登錄Case def login(self, username, password): # 登錄方法,傳入 username 與 password self.login_username().send_keys(username) self.login_password().send_keys(password) self.login_button().click()
# coding:utf-8 from time import sleep from pages.base_page import BasePage # 導(dǎo)入 base_page 層 class OrderPage(BasePage): # 定義 FirstPage(繼承 BasePage ) """ 1、頁面層(登錄頁) - 各個(gè)頁面單獨(dú)封裝成層,頁面的元素、操作、流程 """ def product(self): # 下單 - 第一個(gè)產(chǎn)品 return self.by_xpath("//*[@id='app']/div[1]/div[4]/div[2]/a[1]") def ticket_book(self): # 門票 - 預(yù)定(按鈕) return self.by_xpath("//*[@id='app']/div[1]/div[5]/div[2]/div[2]/a") def book_date(self): # 門票 - 選擇日期 return self.by_xpath("//*[@id='app']/div[1]/form/div[1]/div[1]/div[2]/div/input") def to_order(self): # 門票下單 return self.by_xpath("//*[@id='app']/div[1]/form/div[4]/div/button") def pay_off(self): # 門票下單 - 支付 return self.by_xpath("//*[@id='app']/div[1]/form/div/div/button") def confirm(self): # 門票下單 - 確認(rèn)支付 return self.by_xpath("/html/body/div[5]/div[3]/button[2]") # 下單成功Case def place_order(self): self.product().click() self.ticket_book().click() self.book_date().send_keys("2022-06-16") self.to_order().click() sleep(2) element = self.pay_off() self.driver.execute_script('arguments[0].click()', element) sleep(2)
以上,我們準(zhǔn)備的所有頁面需要準(zhǔn)備的元素定位、基線流程算是寫完了,但是具體的用例,應(yīng)該如何實(shí)現(xiàn)呢?繼續(xù)往下看。
代碼示例如下:
# coding:utf-8 import unittest from time import sleep from selenium import webdriver from pages.home_page import HomePage from pages.login_page import LoginPage from pages.order_page import OrderPage ''' 1、初始化 - 打開瀏覽器,設(shè)置瀏覽器大小 2、最終操作 - 關(guān)閉瀏覽器 3、用例部分 - 登錄 與 購(gòu)買操作、下訂單、支付 ''' class TestTravel(unittest.TestCase): @classmethod def setUpClass(cls): # 每個(gè)測(cè)試類在加載之前執(zhí)行一次 setUpClass ,初始化方法 cls.driver = webdriver.Chrome() cls.driver.maximize_window() def test_a_order(self): #初始化參數(shù) username = '13500000001' password = 'Success@2020' #初始化界面 home_page = HomePage(driver=self.driver, path="http://django.t.mukewang.com/#/") login_page = LoginPage(driver=self.driver) order_page = OrderPage(driver=self.driver) #跳轉(zhuǎn)登錄 home_page.cross_to_login() #登錄 login_page.login(username, password) # 跳轉(zhuǎn)至訂單頁 home_page.cross_to_product() #下單 order_page.place_order() @classmethod def tearDownClass(cls): cls.driver.quit() # 徹底退出瀏覽器 if __name__ == '__main__': unittest.main()
這里改造完成之后,記得將 "BasePage 層" 的 '# self.driver = driver' 取消注釋,并將 'self.driver = webdriver.Chrome()' 注釋掉 。
以上就是一個(gè)比較完整的通過 PO 的方式來連接三個(gè)頁面與基礎(chǔ)的 base_page 來寫出的更簡(jiǎn)潔一些的測(cè)試用例。
運(yùn)行結(jié)果如下:(速度可能過快,擔(dān)待一下,gif 只有15秒的時(shí)間)
讀到這里,這篇“Python中PO模式如何設(shè)計(jì)與實(shí)現(xiàn)”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。