python3+selenium自動(dòng)化測試框架詳解
背景
為了更好的發(fā)展自身的測試技能,應(yīng)對(duì)測試行業(yè)以及互聯(lián)網(wǎng)行業(yè)的迭代變化。自學(xué)python以及自動(dòng)化測試。
雖然在2017年已經(jīng)開始接觸了selenium,期間是斷斷續(xù)續(xù)執(zhí)行自動(dòng)化測試,因?yàn)檫€有其他測試任務(wù),培訓(xùn)任務(wù)要執(zhí)行…
前期建議大家能夠?qū)W習(xí)python基本語法(python基礎(chǔ)教程)
任務(wù)
搭建自動(dòng)化測試框架,并能有效方便的進(jìn)行測試,維護(hù)成本也要考慮其中。
過程
我的自動(dòng)化框架可能不成熟,因?yàn)槭亲詫W(xué)的。請(qǐng)多包涵。也請(qǐng)大佬指導(dǎo)~
common
包含:基本的公共方法類,比如HTML報(bào)告、Log處理、發(fā)送郵件、基本頁面對(duì)象等
其中pageObject里面是對(duì)各個(gè)測試系統(tǒng)操作頁面的一個(gè)封裝,以后用例的方法直接繼承即可??啥啻握{(diào)用,維護(hù)起來比較方便。
conf
基本的系統(tǒng)參數(shù)配置信息,可以包含url,正確用戶的信息,簡單日志級(jí)別,某些輸出位置,郵件信息等
data
對(duì)于數(shù)據(jù)驅(qū)動(dòng)或者其他測試用例中需要測試的數(shù)據(jù),之后測試用例流程不變,可以直接在文檔中進(jìn)行測試數(shù)據(jù)的修改。暫時(shí)采用excel。也可以采用csv,xml等等方法
log
日志輸出,暫時(shí)包括了 log輸出,htmlreport輸出以及img的保存。
test
其中包含testcase以及testsuite兩個(gè)模塊
testcase 負(fù)責(zé)編寫測試用例如果某個(gè)功能有多個(gè)py文件編寫可以再新建一個(gè)目錄。
testsuite 就是測試套件,可以按需求進(jìn)行選擇需要的測試項(xiàng)(包含測試用例以及測試類)
注意:使用ddt則不可以再使用addTest方式單獨(dú)添加測試用例了。
1
代碼部分
- common中的BasePage
class BasePage(): global logg logg = LogHandler().logger def __init__(self,driver,url=None): self.wd = driver self.wd.implicitly_wait(5) self.actions = ActionChains(self.wd) if url : self.url = url else: self.url = self.server_url_conf() #瀏覽器行為的一些方法 def get_conf_url(self): self.wd.get(self.url) self.wd.maximize_window() logg.debug("enter conf_url : " + str(self.url)) def brower_close(self): return self.wd.close() def brower_quit_all(self): return self.wd.quit() ... 下面還有刷新,前進(jìn)后退等 #定位 這里通過 By.xx 方法 def find_web_element(self,*loc): #self.wd.find_element(*loc) return self.wd.find_element(*loc) #元素操作 def type_text(self,loc,text): return self.wd.find_element(*loc).send_keys(text) def clear_text(self,*loc): return self.wd.find_element(*loc).clear() def submit_func(self,*loc): return self.wd.find_element(*loc).submit() def click_btn(self,*loc): return self.wd.find_element(*loc).click() #鼠標(biāo)相關(guān) def mouse_move_to_element(self,*loc): elem = self.find_web_element(*loc) self.actions.move_to_element(elem).perform() ... 下面還有點(diǎn)擊,雙擊,右擊的一些方法 #獲取信息行為 def get_web_url(self): return self.wd.current_url def get_title(self): return self.wd.title def get_element_text(self,*loc): return self.find_web_element(*loc).text #元素是否存在 是 True def check_element_isexist(self,loc): isexist = False try: EC.presence_of_element_located(loc)(self.wd) isexist = True except Exception as e: isexist = False logg.debug(' isexist or not :',exc_info = True) return isexist def check_element_has_text(self,loc,text): pass #省略 def check_element_isdisplayed(self,*loc): pass #省略 #生成圖 def __inser_img(self,passorfailed,imgname): time_loc = time.strftime("%m%d_%H%M%S",time.localtime()) file_path = os.path.abspath(__file__) file_path = os.path.join(file_path+"/../../log/%s_%s.png" %(imgname,time_loc)) self.wd.get_screenshot_as_file(file_path) logg.debug('insert_%s_img %s ' %(passorfailed,(file_path))) def insert_error_img(self,imgname): self.__inser_img("error",imgname) def insert_success_img(self,imgname): self.__inser_img("success",imgname) def insert_debug_img(self,imgname): self.__inser_img("debug",imgname) def server_url_conf(self): self.host = readconfig.ReadConfig().getserver('host') self.port = readconfig.ReadConfig().getserver('port') urlvalue = self.host + ":" + self.port return urlvalue if __name__ == '__main__': test = BasePage(webdriver.Chrome()) test.get_conf_url()
common中登錄頁的頁面對(duì)象
包含了頁面的一些方法比如
輸入用戶名,輸入密碼,點(diǎn)擊登錄
test中的 logintestcase
則直接使用 登錄頁面對(duì)象的 輸入用戶名,輸入密碼,點(diǎn)擊登錄即可
后期維護(hù),如果元素變動(dòng),則只需要修改頁面對(duì)象代碼而對(duì)用例則無需修正
class AioLogin(BasePage): global logg logg = LogHandler().getlog() username_loc = (By.NAME, "username") password_loc = (By.CSS_SELECTOR, "input[type='password']") login_loc = (By.CLASS_NAME, "login-btn") login_loc_oem = (By.ID,"submit") check_login_loc = (By.CLASS_NAME,"error-tip") elements = [username_loc,password_loc,login_loc,check_login_loc] log_menu = (By.CSS_SELECTOR,"[name='log']") logg.debug(elements) def set_username(self,username): self.clear_text(*self.username_loc) #直接使用BasePage的方法 self.type_text(self.username_loc,username) logg.info('Enter username: ' + username) sleep(0.1) ... 其他
logintest
這里使用了ddt數(shù)據(jù)驅(qū)動(dòng)方法
from ddt import data,ddt,unpack
@ddt class TestLogin(unittest.TestCase): global logg logg = LogHandler().getlog() @classmethod #該類方法,執(zhí)行中只會(huì)啟動(dòng)一次。區(qū)別于setUp的 每個(gè)用例都執(zhí)行一遍 def setUpClass(cls): cls.test = aiologinpage.AioLogin(webdriver.Chrome()) cls.test.get_conf_url() # print('start TestSearch') @classmethod def tearDownClass(cls): # TestLogin().logg.info("brower quit") TestLogin().test.brower_close() pass logindata = ReadExcel().getValue('login') @data(*logindata) @unpack #當(dāng)有多組數(shù)據(jù)時(shí),需要unpack def testcase2(self,username,passwd,result): logg.info(username+" " + passwd +" " +str(result)) self.test.set_username(username) #用例直接使用登錄頁面對(duì)象,后期除了修改測試用例,否則無需變動(dòng) self.test.set_password(passwd) self.test.type_login_btn() # 斷言登錄結(jié)果和預(yù)期結(jié)果是否一致 self.assertTrue(self.test.check_login_result(result), msg="\r login_test fail \r username :%s \r passwd : %s " %(username,passwd)) if __name__ == '__main__': unittest.main()
其他頁面
比如我有個(gè) 創(chuàng)建設(shè)備分組的頁面
我必須要先登錄才可以執(zhí)行下面的操作
此時(shí),可以從conf中獲取成功登錄的用戶名和密碼,把correct_login方法寫在登錄頁面對(duì)象中。
def correct_login(self): self.get_conf_url() self.userpasswd = self.correct_userpasswd_conf() self.set_username(self.userpasswd[0]) self.set_password(self.userpasswd[1]) self.type_login_btn()
之后,其他頁面初始化時(shí)候直接調(diào)用這個(gè)correct_login即可登錄
測試套件添加方法
TestSuite方法
#添加一個(gè)類
st1 = unittest.makeSuite(TestLogin)
#單獨(dú)添加多個(gè)用例
st = unittest.TestSuite(map(TestClassName,[‘testcase1',‘testcase2']))
st = unittest.TestSuite(TestClaseeName(‘testcase1'))#添加一個(gè)或者多個(gè)測試用例
st2 = unittest.TestSuite()
st2.addTests(map(TestCaseClassName,[‘testcase2',‘testcase1']))
st2.addTest(TestCaseClassName(‘testcase1'))
#添加一個(gè)類
st2.addTest(unittest.makeSuite(TestClassName))TestLoader 方法
discovery 發(fā)現(xiàn)腳本
st = unittest.TestLoader().discovery(“dir_path”,pattern=“a*.py”)#loadTestFromTestCase 加載 測試類
st1 = unittest.TestLoader().loadTestsFromTestCase(TestLoginCheck)
st2 = unittest.TestLoader().loadTestsFromTestCase(TestLogin)
stt = unittest.TestSuite()
stt.addTests([st1,st2])
- python自動(dòng)化測試實(shí)例解析
- Python自動(dòng)化測試工具Splinter簡介和使用實(shí)例
- Python + selenium自動(dòng)化環(huán)境搭建的完整步驟
- Python PyAutoGUI模塊控制鼠標(biāo)和鍵盤實(shí)現(xiàn)自動(dòng)化任務(wù)詳解
- python自動(dòng)化實(shí)現(xiàn)登錄獲取圖片驗(yàn)證碼功能
- Python 自動(dòng)化表單提交實(shí)例代碼
- python實(shí)現(xiàn)報(bào)表自動(dòng)化詳解
- selenium+python實(shí)現(xiàn)自動(dòng)化登錄的方法
- python自動(dòng)化實(shí)現(xiàn)的簡單使用
相關(guān)文章
Python高級(jí)property屬性用法實(shí)例分析
這篇文章主要介紹了Python高級(jí)property屬性用法,結(jié)合實(shí)例形式分析了Python property屬性的功能及各種常見的使用技巧,需要的朋友可以參考下2019-11-11Python實(shí)現(xiàn)線程狀態(tài)監(jiān)測簡單示例
這篇文章主要介紹了Python實(shí)現(xiàn)線程狀態(tài)監(jiān)測,結(jié)合簡單實(shí)例形式分析了Python線程start啟動(dòng)、sleep推遲運(yùn)行、isAlive判斷等方法使用技巧,需要的朋友可以參考下2018-03-03Python網(wǎng)絡(luò)爬蟲之獲取網(wǎng)絡(luò)數(shù)據(jù)
本文介紹了Python中用于獲取網(wǎng)絡(luò)數(shù)據(jù)的重要工具之一——Requests庫,詳細(xì)講解了Requests庫的基本使用方法、請(qǐng)求方法、請(qǐng)求頭、請(qǐng)求參數(shù)、Cookies、Session等內(nèi)容,并結(jié)合實(shí)例代碼展示了Requests庫的應(yīng)用場景2023-04-04卷積神經(jīng)網(wǎng)絡(luò)經(jīng)典模型及其改進(jìn)點(diǎn)學(xué)習(xí)匯總
這篇文章主要為大家介紹了卷積神經(jīng)網(wǎng)絡(luò)經(jīng)典模型及其改進(jìn)點(diǎn)學(xué)習(xí)匯總,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05