晉江免費網(wǎng)站建設(shè)網(wǎng)絡(luò)推廣包括哪些
初識PO模式
PO(PageObject)是一種設(shè)計模式。簡單來說就是把一些繁瑣的定位方法、元素操作方式等封裝到類中,通過類與類之間的調(diào)用完成特定操作。
PO被認(rèn)為是自動化測試項目開發(fā)實踐的最佳設(shè)計模式之一。
在學(xué)習(xí)PO模式前,可以先復(fù)習(xí)一下面向?qū)ο蟮木幊趟枷?。我覺得兩者很像。
優(yōu)點
- PO模式把頁面元素定位和業(yè)務(wù)操作流程分開,界面元素的變化則不需要修改業(yè)務(wù)邏輯代碼
- PO能提高代碼的可讀性,高復(fù)用性,可維護(hù)性
設(shè)計準(zhǔn)則
1.使用公共方法來代表頁面提供的服務(wù)
2.不要暴露頁面的內(nèi)部細(xì)節(jié)(比如元素、元素的定位方法等),隔離測試用例和業(yè)務(wù)和頁面對象
3.PO本身通常不應(yīng)進(jìn)行斷言或判斷。判斷和斷言是測試的一部分,而不是在PO中。
4.PO不一定需要代表整個界面,而是在測試中‘用到什么寫什么’
5.相同的操作,但是數(shù)據(jù)不同,帶來的不同結(jié)果可以封裝成不同的方法。
6.方法可以返回其他的頁面對象,進(jìn)行頁面的關(guān)聯(lián)。
以上是比較官方的PO設(shè)計準(zhǔn)則,我們需要根據(jù)具體業(yè)務(wù)的實際情況決定是完全遵循還是部分遵循。
?現(xiàn)在我也找了很多測試的朋友,做了一個分享技術(shù)的交流群,共享了很多我們收集的技術(shù)文檔和視頻教程。
如果你不想再體驗自學(xué)時找不到資源,沒人解答問題,堅持幾天便放棄的感受
可以加入我們一起交流。而且還有很多在自動化,性能,安全,測試開發(fā)等等方面有一定建樹的技術(shù)大牛
分享他們的經(jīng)驗,還會分享很多直播講座和技術(shù)沙龍
可以免費學(xué)習(xí)!劃重點!開源的!!!
qq群號:485187702【暗號:csdn11】
selenium中的分層模型
- 表現(xiàn)層:頁面中可見的元素,都屬于表現(xiàn)層。(元素定位器的編寫)
- 操作層:對頁面可見元素的操作。(點擊、輸入文本等)
- 業(yè)務(wù)層:上面2層的組合,聯(lián)合到一起形成某個業(yè)務(wù)動作。
- 測試用例:組合了一個或多個頁面的方法,操作對應(yīng)的元素,完成的測試。
PO模式實戰(zhàn)
接下來就用PO模式完成一個簡單的‘百度登錄模塊’的測試
思路:
1.創(chuàng)建一個elements.py存放登錄界面所有的元素定位方式(用到哪個寫哪個)
2.創(chuàng)建一個common_driver.py存放一些共用的瀏覽器相關(guān)方法
3.創(chuàng)建一個common_basepage.py存放共用的元素操作方法
4.創(chuàng)建一個test_cases.py文件存放測試用例
以下為部分代碼:
- 找到我們測試登錄模塊需要操作到的元素,將其定位方法寫到elements.py中
#elements.pyclass Elements():'''存放用到的所有元素定位器'''#登錄前的界面元素LOGIN_BUTTON_OUT = ('id','s-top-loginbtn')#百度首頁的‘登錄’按鈕LOGIN_WIN = ('id','TANGRAM__PSP_4__content')#登錄窗口USERNAME_INPUT = ('id','TANGRAM__PSP_11__userName')#輸入賬號欄PASSWORD_INPUT = ('id','TANGRAM__PSP_11__password')#輸入密碼欄LOGIN_BUTTON_IN = ('id','TANGRAM__PSP_11__submit')#登錄界面的‘登錄’按鈕#登錄后的界面元素USER_INFO = ('css selector','#s-top-username > span.user-name.c-font-normal.c-color-t')#右上角的用戶信息QUIT_BOTTON = ('css selector','#s-user-name-menu>.quit')#退出登錄按鈕
- 瀏覽器相關(guān)操作放到common_driver.py中
# common_driver.pyfrom selenium import webdriver
from environment_config import Envclass Single(object):'''設(shè)計單例模式'''_instance = None #實例def __new__(cls, *args, **kwargs):if cls._instance is None: #此處是可以用__instancecls._instance = super().__new__(cls)return cls._instance
class Open_Driver(Single):'''打開一個瀏覽器'''driver = Nonedef get_driver(self,browser_type=Env.BROWSER_TYPE,headless_flag=Env.HEADLESS_FLAG):'''根據(jù)參數(shù)打開想要的瀏覽器:param browser_type: 瀏覽器類型,讀取Env文件中的值作為默認(rèn)值:param headless_flag: 是否有頭,讀取Env文件中的值作為默認(rèn)值,True/False:return: 返回一個瀏覽器對象'''if self.driver is None:if not headless_flag:#如果是有頭模式if browser_type == 'chrome':self.driver = webdriver.Chrome()elif headless_flag == 'firefox':self.driver = webdriver.Firefox()else:raise Exception(f'暫不支持{browser_type}瀏覽器')else:#如果是無頭模式_option = webdriver.ChromeOptions()_option.add_argument('--headless')#添加無頭模式參數(shù)'--headless'if browser_type == 'chrome':self.driver = webdriver.Chrome(options=_option)elif headless_flag == 'firefox':self.driver = webdriver.Firefox(options=_option)else:raise Exception(f'暫不支持{browser_type}瀏覽器')self.driver.maximize_window()#窗口最大化self.driver.implicitly_wait(Env.IMPLICITLY_WAIT_TIME)#隱式等待,讀取Env文件中IMPLICITLY_WAIT_TIME的值return self.driver #返回瀏覽器對象
- 把要用到的元素操作方法寫入到common_basepage.py中
# common_basepage.py
from common_driver import Open_Driverclass BasePage():'''存放所有界面元素操作方法'''def __init__(self):self.driver = Open_Driver().get_driver()def open_url(self,url):'''打開網(wǎng)址'''self.driver.get(url)def get_element(self,locator):'''定位元素:param locator:元素定位器,從elements中取:return: 元素對象'''return self.driver.find_element(*locator)def input_text(self,locator,text,append=False):'''在元素上輸入文本:param locator: 元素定位器:param text: 要輸入的文本:param append: 是否先清空,默認(rèn)清空'''if append:#不需要清空內(nèi)容,追加寫入self.driver.find_element(*locator).send_keys(text)else:#先清空,再寫入self.driver.find_element(*locator).clear()self.driver.find_element(*locator).send_keys(text)def click_element(self,locator):'''點擊元素:param locator: 元素定位器'''self.driver.find_element(*locator).click()def ele_find_ele_input(self,locator1,locator2,text):'''在元素1上找元素2:param ele1: 元素1:param ele2: 元素2:return: 元素2'''return self.driver.find_element(*locator1).find_element(*locator2).send_keys(text)def get_element_text(self,locator):return self.driver.find_element(*locator).text
- 頁面對象loginpage.py
from common_basepage import BasePage
from datas import Datas
from elements import Elements
from logsuccesspage import LogSuccessPageclass LoginPage(BasePage):def open_loginpage(self,url):'''打開登錄頁:param url:登錄頁url:return: LoginPage實例對象'''self.open_url(url)return selfdef login_baidu(self,username,password):'''登錄百度賬號:param username: 用戶名:param password: 密碼:return: 登錄成功后的頁面對象'''self.click_element(Elements.LOGIN_BUTTON_OUT)#點擊右上角登錄self.ele_find_ele_input(Elements.LOGIN_WIN,Elements.USERNAME_INPUT,Datas.USERNAME)#輸入賬號self.ele_find_ele_input(Elements.LOGIN_WIN,Elements.PASSWORD_INPUT,Datas.PASSWORD)#輸入密碼self.click_element(Elements.LOGIN_BUTTON_IN)return LogSuccessPage()
- 測試用例test_cases.py
from time import sleep
import pytest
from datas import Datas
from elements import Elements
from environment_config import Env
from loginpage import LoginPageclass Test_login():def test_login01(self):'''登錄成功的測試:return:'''test_page = LoginPage()#創(chuàng)建實例test_page.open_loginpage(Env.TEST_URL)#打開測試urlnew_page=test_page.login_baidu(Datas.USERNAME,Datas.PASSWORD)#登錄百度賬號sleep(2)text = new_page.get_element_text(Elements.USER_INFO)#登錄成功界面assert text == 'yvvgfffvbh'#斷言用戶名稱是否正確if __name__ == '__main__':pytest.main(['-vs'])
- 運行結(jié)果
寫完花了4個小時,感受就是:
1.要理解透徹Python中的面向?qū)ο笏枷搿?/p>
2.寫完整體結(jié)構(gòu)后要繼續(xù)優(yōu)化。
可以看到,我們所有數(shù)據(jù)都放在配置文件中,代碼中不會暴露任何的界面元素或賬號數(shù)據(jù)。 最后用pytest執(zhí)行測試用例即可。
以上只是一個最簡版的PO模型項目。只是遵循了po設(shè)計準(zhǔn)則,并不完整。
一個完整的selenium測試項目大體上應(yīng)該包括:
1.tools 工具類,格式轉(zhuǎn)換、路徑操作等
2.commom 基類,一些公用的方法
3.pageobjects 頁面對象類
4.testcases 測試用例
5.test_datas 測試數(shù)據(jù),yaml/Excel文件等
6.outfiles 輸出文件,log和截圖等
7.testreport 測試報告
項目結(jié)構(gòu)并沒有具體標(biāo)準(zhǔn),分類清晰即可。重要的是在設(shè)計過程中遵循上文說到的’設(shè)計準(zhǔn)則‘。
?
最后感謝每一個認(rèn)真閱讀我文章的人,看著粉絲一路的上漲和關(guān)注,禮尚往來總是要有的,雖然不是什么很值錢的東西,如果你用得到的話可以直接拿走!?希望能幫助到你!【100%無套路免費領(lǐng)取】