python+selenium自動化測試框架詳解,我就講一遍

前言

本文整理歸納以往的工作中用到的東西,現彙總成基礎測試框架提供分享。

框架採用python3 + selenium3 + PO + yaml + ddt + unittest等技術編寫成基礎測試框架,能適應日常測試工作需要。

1、使用Page Object模式將頁面定位和業務操作分開,分離測試物件(元素物件)和測試指令碼(用例指令碼),一個頁面建一個物件類,提高用例的可維護性;

2、使用yaml管理頁面控制元件元素資料和測試用例資料。例如元素ID等發生變化時,不需要去修改測試程式碼,只需要在對應的頁面元素yaml檔案中修改即可;

3、分模組管理,互不影響,隨時組裝,即拿即用。

1、測試框架分層設計

python+selenium自動化測試框架詳解,我就講一遍

把常見的操作和查詢封裝成基礎類,不管是什麼產品,可直接拿來複用

業務層主要是封裝物件頁面類,一個頁面建一個類,業務層頁面繼承基礎層

用例層針對產品頁面功能進行構造摸擬執行測試

框架層提供基礎元件,支撐整個流程執行及功能擴充套件,給用例層提供各頁面的元素資料、用例測試資料,測試報告輸出等

2、測試框架目錄結構

python+selenium自動化測試框架詳解,我就講一遍

如下思維導圖目錄結構介紹:

python+selenium自動化測試框架詳解,我就講一遍

3、編寫用例方法

testinfo: 2 - id: test_login001 3 title: 登入測試 4 info: 開啟抽屜首頁 5 testcase: 6 - element_info: login-link-a 7 find_type: ID 8 operate_type: click 9 info: 開啟登入對話方塊10 - element_info: mobile11 find_type: ID12 operate_type: send_keys13 info: 輸入手機號14 - element_info: mbpwd15 find_type: ID16 operate_type: send_keys17 info: 輸入密碼18 - element_info: //input[@class=‘keeplogin’]19 find_type: XPATH20 operate_type: click21 info: 單擊取消自動登入單選框22 - element_info: //span[text()=‘登入’]23 find_type: XPATH24 operate_type: click25 info: 單擊登入按鈕26 - element_info: userProNick27 find_type: ID28 operate_type: perform29 info: 滑鼠懸停賬戶選單30 - element_info: //a[@class=‘logout’]31 find_type: XPATH32 operate_type: click33 info: 選擇退出34 check:35 - element_info: //div[@class=‘box-mobilelogin’]/div[1]/span36 find_type: XPATH37 info: 檢查輸入手機號或密碼,登入異常提示38 - element_info: userProNick39 find_type: ID40 info: 成功登入41 - element_info: reg-link-a42 find_type: ID43 info: 檢查退出登入是否成功

例如,我們要新增登入功能測試用例:

首先,只需在testyaml目錄下新增一個頁面物件yaml檔案,參考login。yaml格式編寫即可。這些檔案是提供給封裝頁面物件類呼叫並執行定位識別操作。

1 - 2 id: test_login001。1 3 detail : 手機號和密碼為空登入 4 screenshot : phone_pawd_empty 5 data: 6 phone: “” 7 password: “” 8 check : 9 - 手機號不能為空10 -11 id: test_login001。212 detail : 手機號為空登入13 screenshot : phone_empty14 data :15 phone: “”16 password : aa17 check :18 - 手機號不能為空19 -20 id: test_login001。321 detail : 密碼為空登入22 screenshot : pawd_empty23 data :24 phone : 1351111222225 password: “”26 check :27 - 密碼不能為空28 -29 id: test_login001。430 detail : 非法手機號登入31 screenshot : phone_error32 data :33 phone : abc34 password: aa35 check :36 - 手機號格式不對37 -38 id: test_login001。539 detail : 手機號或密碼不匹配40 screenshot : pawd_error41 data :42 phone : 1351111222243 password: aa44 check :45 - 賬號密碼錯誤46 -47 id: test_login001。648 detail : 手機號和密碼正確49 screenshot : phone_pawd_success50 data :51 phone : 1386543980052 password: ********53 check :54 - yingoja55 56 login_data。yaml

其次,在testdata目錄下新增一個login_data。yaml檔案提供給登入介面傳參的測試資料,編寫格式參考login_data。yaml檔案。

1 #!/usr/bin/env python 2 # _*_ coding:utf-8 _*_ 3 __author__ = ‘YinJia’ 4 5 import os,sys 6 sys。path。append(os。path。dirname(os。path。dirname(os。path。dirname(__file__)))) 7 from config import setting 8 from selenium。webdriver。support。select import Select 9 from selenium。webdriver。common。action_chains import ActionChains 10 from selenium。webdriver。common。by import By 11 from public。page_obj。base import Page 12 from time import sleep 13 from public。models。GetYaml import getyaml 14 15 testData = getyaml(setting。TEST_Element_YAML + ‘/’ + ‘login。yaml’) 16 17 class login(Page): 18 “”“ 19 使用者登入頁面 20 ”“” 21 url = ‘/’ 22 dig_login_button_loc = (By。ID, testData。get_elementinfo(0)) 23 def dig_login(self): 24 “”“ 25 首頁登入 26 :return: 27 ”“” 28 self。find_element(*self。dig_login_button_loc)。click() 29 sleep(1) 30 31 # 定位器,透過元素屬性定位元素物件 32 # 手機號輸入框 33 login_phone_loc = (By。ID,testData。get_elementinfo(1)) 34 # 密碼輸入框 35 login_password_loc = (By。ID,testData。get_elementinfo(2)) 36 # 取消自動登入 37 keeplogin_button_loc = (By。XPATH,testData。get_elementinfo(3)) 38 # 單擊登入 39 login_user_loc = (By。XPATH,testData。get_elementinfo(4)) 40 # 退出登入 41 login_exit_loc = (By。ID, testData。get_elementinfo(5)) 42 # 選擇退出 43 login_exit_button_loc = (By。XPATH,testData。get_elementinfo(6)) 44 45 def login_phone(self,phone): 46 “”“ 47 登入手機號 48 :param username: 49 :return: 50 ”“” 51 self。find_element(*self。login_phone_loc)。send_keys(phone) 52 53 def login_password(self,password): 54 “”“ 55 登入密碼 56 :param password: 57 :return: 58 ”“” 59 self。find_element(*self。login_password_loc)。send_keys(password) 60 61 def keeplogin(self): 62 “”“ 63 取消單選自動登入 64 :return: 65 ”“” 66 self。find_element(*self。keeplogin_button_loc)。click() 67 68 def login_button(self): 69 “”“ 70 登入按鈕 71 :return: 72 ”“” 73 self。find_element(*self。login_user_loc)。click() 74 75 def login_exit(self): 76 “”“ 77 退出系統 78 :return: 79 ”“” 80 above = self。find_element(*self。login_exit_loc) 81 ActionChains(self。driver)。move_to_element(above)。perform() 82 sleep(2) 83 self。find_element(*self。login_exit_button_loc)。click() 84 85 def user_login(self,phone,password): 86 “”“ 87 登入入口 88 :param username: 使用者名稱 89 :param password: 密碼 90 :return: 91 ”“” 92 self。open() 93 self。dig_login() 94 self。login_phone(phone) 95 self。login_password(password) 96 sleep(1) 97 self。keeplogin() 98 sleep(1) 99 self。login_button()100 sleep(1)101 102 phone_pawd_error_hint_loc = (By。XPATH,testData。get_CheckElementinfo(0))103 user_login_success_loc = (By。ID,testData。get_CheckElementinfo(1))104 exit_login_success_loc = (By。ID,testData。get_CheckElementinfo(2))105 106 # 手機號或密碼錯誤提示107 def phone_pawd_error_hint(self):108 return self。find_element(*self。phone_pawd_error_hint_loc)。text109 110 # 登入成功使用者名稱111 def user_login_success_hint(self):112 return self。find_element(*self。user_login_success_loc)。text113 114 # 退出登入115 def exit_login_success_hint(self):116 return self。find_element(*self。exit_login_success_loc)。text

然後,在page_obj目錄下新增一個loginPage。py檔案,是用來封裝登入頁面物件類,執行登入測試流程操作。

1 #!/usr/bin/env python 2 # _*_ coding:utf-8 _*_ 3 __author__ = ‘YinJia’ 4 5 6 import os,sys 7 sys。path。append(os。path。dirname(os。path。dirname(__file__))) 8 import unittest,ddt,yaml 9 from config import setting10 from public。models import myunit,screenshot11 from public。page_obj。loginPage import login12 from public。models。log import Log13 14 try:15 f =open(setting。TEST_DATA_YAML + ‘/’ + ‘login_data。yaml’,encoding=‘utf-8’)16 testData = yaml。load(f)17 except FileNotFoundError as file:18 log = Log()19 log。error(“檔案不存在:{0}”。format(file))20 21 @ddt。ddt22 class Demo_UI(myunit。MyTest):23 “”“抽屜新熱榜登入測試”“”24 def user_login_verify(self,phone,password):25 “”“26 使用者登入27 :param phone: 手機號28 :param password: 密碼29 :return:30 ”“”31 login(self。driver)。user_login(phone,password)32 33 def exit_login_check(self):34 “”“35 退出登入36 :return:37 ”“”38 login(self。driver)。login_exit()39 40 @ddt。data(*testData)41 def test_login(self,datayaml):42 “”“43 登入測試44 :param datayaml: 載入login_data登入測試資料45 :return:46 ”“”47 log = Log()48 log。info(“當前執行測試用例ID-> {0} ; 測試點-> {1}”。format(datayaml[‘id’],datayaml[‘detail’]))49 # 呼叫登入方法50 self。user_login_verify(datayaml[‘data’][‘phone’],datayaml[‘data’][‘password’])51 po = login(self。driver)52 if datayaml[‘screenshot’] == ‘phone_pawd_success’:53 log。info(“檢查點-> {0}”。format(po。user_login_success_hint()))54 self。assertEqual(po。user_login_success_hint(), datayaml[‘check’][0], “成功登入,返回實際結果是->: {0}”。format(po。user_login_success_hint()))55 log。info(“成功登入,返回實際結果是->: {0}”。format(po。user_login_success_hint()))56 screenshot。insert_img(self。driver, datayaml[‘screenshot’] + ‘。jpg’)57 log。info(“——-> 開始執行退出流程操作”)58 self。exit_login_check()59 po_exit = login(self。driver)60 log。info(“檢查點-> 找到{0}元素,表示退出成功!”。format(po_exit。exit_login_success_hint()))61 self。assertEqual(po_exit。exit_login_success_hint(), ‘註冊’,“退出登入,返回實際結果是->: {0}”。format(po_exit。exit_login_success_hint()))62 log。info(“退出登入,返回實際結果是->: {0}”。format(po_exit。exit_login_success_hint()))63 else:64 log。info(“檢查點-> {0}”。format(po。phone_pawd_error_hint()))65 self。assertEqual(po。phone_pawd_error_hint(),datayaml[‘check’][0] , “異常登入,返回實際結果是->: {0}”。format(po。phone_pawd_error_hint()))66 log。info(“異常登入,返回實際結果是->: {0}”。format(po。phone_pawd_error_hint()))67 screenshot。insert_img(self。driver,datayaml[‘screenshot’] + ‘。jpg’)68 69 if __name__==‘__main__’:70 unittest。main()

最後,在testcase目錄下建立測試用例檔案login_sta。py,採用ddt資料驅動讀取yaml測試資料檔案

綜上所述,編寫用例方法只需要按以上四個步驟建立->編寫即可。

執行如下主程式,可看輸出的實際結果。

1 #!/usr/bin/env python 2 # _*_ coding:utf-8 _*_ 3 __author__ = ‘YinJia’ 4 5 import os,sys 6 sys。path。append(os。path。dirname(__file__)) 7 from config import setting 8 import unittest,time 9 from package。HTMLTestRunner import HTMLTestRunner10 from public。models。newReport import new_report11 from public。models。sendmail import send_mail12 13 # 測試報告存放資料夾,如不存在,則自動建立一個report目錄14 if not os。path。exists(setting。TEST_REPORT):os。makedirs(setting。TEST_REPORT + ‘/’ + “screenshot”)15 16 def add_case(test_path=setting。TEST_DIR):17 “”“載入所有的測試用例”“”18 discover = unittest。defaultTestLoader。discover(test_path, pattern=‘*_sta。py’)19 return discover20 21 def run_case(all_case,result_path=setting。TEST_REPORT):22 “”“執行所有的測試用例”“”23 now = time。strftime(“%Y-%m-%d %H_%M_%S”)24 filename = result_path + ‘/’ + now + ‘result。html’25 fp = open(filename,‘wb’)26 runner = HTMLTestRunner(stream=fp,title=‘抽屜新熱榜UI自動化測試報告’,27 description=‘環境:windows 7 瀏覽器:chrome’,28 tester=‘Jason’)29 runner。run(all_case)30 fp。close()31 report = new_report(setting。TEST_REPORT) #呼叫模組生成最新的報告32 send_mail(report) #呼叫傳送郵件模組33 34 if __name__ ==“__main__”:35 cases = add_case()36 run_case(cases)

4、測試結果展示

HTML報告日誌

python+selenium自動化測試框架詳解,我就講一遍

HTML報告點選截圖,彈出截圖

python+selenium自動化測試框架詳解,我就講一遍

測試報告透過的日誌

python+selenium自動化測試框架詳解,我就講一遍

自動截圖存放指定的目錄

python+selenium自動化測試框架詳解,我就講一遍

郵件測試報告

python+selenium自動化測試框架詳解,我就講一遍

5、總結

感謝每一個認真閱讀我文章的人!!!

如果下面這些資料用得到的話可以直接拿走:

1、自學開發或者測試必備的完整專案原始碼與環境

2、測試工作中所有模板(測試計劃、測試用例、測試報告等)

3、軟體測試經典面試題

4、Python/Java自動化測試實戰.pdf

5、Jmeter/postman介面測試全套影片獲取

6、Python學習路線圖

python+selenium自動化測試框架詳解,我就講一遍

重點:配套學習資料和影片教學

那麼在這裡我也精心準備了上述大綱的詳細資料

包含:電子書,簡歷模組,各種工作模板,面試寶典,自學專案等。如下,需要的評論區留言或者私信我

python+selenium自動化測試框架詳解,我就講一遍

python+selenium自動化測試框架詳解,我就講一遍