接口測試學習-python第八課(數據驅動測試)
阿新 • • 發佈:2018-06-02
檢查 QQ PE pat spl spa 授權 記錄日誌 日誌格式
自動化分為三類,數據驅動即根據數據去進行測試;代碼驅動即測試都是通過代碼完成的;關鍵字驅動即依靠一些軟件,利用關鍵字完成測試。本次主要記錄數據驅動,自動化框架主要有以下幾個部分:
①獲取用例
②調用接口
③檢驗結果
④發送測試報告
⑤異常處理
⑥日誌
以前進行接口封裝的時候,有過將代碼分別放在不同的文件夾下的經歷。這次也以這樣的模式來完成,主要做到以下幾點:首先讀取用例,其次根據用例完成接口測試,然後記錄結果到用例文件中,最後發送郵件。同時各個部分關鍵結果處需要記錄日誌。
1、setting文件
setting文件一般放在config文件夾下。這個代碼因為涉及到發送郵件,讀取excel,寫日誌等。所以基礎數據包括郵件的host,賬號,密碼等;還有文件地址和日誌地址等。這些數據在後面的代碼中都會使用到。
1 import os 2 3 4 # 發送郵件的一些固定參數,在sendmail函數中會使用到,可以在此處修改,此處的password是授權碼 5 MAIL_HOST = ‘smtp.163.com‘ 6 MAIL_USER = ‘********@163.com‘ 7 MAIL_PASSWORD = *****‘ # 授權碼 8 MAIL_TO = ‘[email protected]‘ 9 10 BASE_PATH = os.path.dirname( 11 os.path.dirname(os.path.abspath(__file__)) 12 ) #找到APT這個文件夾的地址 13 LOG_PATH = os.path.join(BASE_PATH, ‘logs‘) # 拼接出存放日誌的路徑 14 CASE_PATH = os.path.join(BASE_PATH, ‘cases‘) # 拼接出存放用例的路徑 15 16 LEVEL = ‘debug‘ # 日誌級別 17 LOG_NAME = ‘apt.log‘ # 日誌文件名
2、日誌模塊
這個模塊主要內容就是日誌記錄的功能。構造了一個可實例化的類,實例化後在其他模塊可以直接調用生成相應等級的日誌。
1 import logging 2 import os 3 fromlogging import handlers 4 from config import setting 5 6 7 class MyLogger(object): 8 def __init__(self,file_name,level=‘info‘,backCount=5,when=‘D‘): 9 logger = logging.getLogger() 10 logger.setLevel(self.get_level(level)) # 設置日誌的級別 11 # fl = logging.FileHandler(filename=‘a.log‘, mode=‘a‘, encoding=‘utf-8‘) 12 cl = logging.StreamHandler() # 負責往控制臺輸出的 13 bl = handlers.TimedRotatingFileHandler(filename=file_name, when=when, interval=1, 14 backupCount=backCount, encoding=‘utf-8‘) 15 fmt = logging.Formatter(‘%(asctime)s - %(pathname)s[line:%(lineno)d]-%(levelname)s:%(message)s‘) 16 # 指定日誌的格式 17 cl.setFormatter(fmt) # 設置控制臺輸出的日誌格式 18 bl.setFormatter(fmt) # 設置文件裏面寫入的日誌格式 19 logger.addHandler(cl) # 把已經設置好的人放到辦公室中 20 logger.addHandler(bl) # 同上 21 self.logger = logger 22 23 def get_level(self, sss): 24 level = { 25 ‘debug‘: logging.DEBUG, 26 ‘info‘: logging.INFO, 27 ‘warn‘: logging.WARN, 28 ‘error‘: logging.ERROR 29 } 30 sss = sss.lower() 31 return level.get(sss) 32 33 path = os.path.join(setting.LOG_PATH, setting.LOG_NAME) # 拼好日誌的絕對路徑 34 apt_log = MyLogger(path, setting.LEVEL).logger 35 # 直接在這邊實例化,並.logger,使用時就可以直接apt_log.warning了
3、發送郵件模塊
用於記錄發送郵件的功能,這裏就用到了setting裏面記錄的那些基礎數據,還用到了日誌記錄功能。
1 import yagmail 2 from config import setting 3 from lib.log import apt_log 4 5 6 def sendemile(title, content, attrs=None): # 定義發送郵件函數 7 m = yagmail.SMTP(host=setting.MAIL_HOST, # host調用setting文件中設置的固定參數 8 user=setting.MAIL_USER, # user調用setting文件中設置的固定參數 9 password=setting.MAIL_PASSWORD # password調用setting文件中設置的固定參數 10 ) 11 m.send(to=setting.MAIL_TO, 12 subject=title, 13 contents=content, 14 attachments=attrs 15 ) # 郵件發送主體內容,收件人使用固定參數,其他內容在調用函數時傳入 16 apt_log.info(‘郵件發送成功。‘) # 寫入發送郵件成功的日誌
4、讀取用例進行測試並記錄測試結果模塊
這是一個主體模塊,完成了這個文件的主要功能。詳細代碼如下。
1 import xlrd 2 from lib.log import apt_log 3 import requests 4 from xlutils import copy 5 6 7 class OpCase(object): 8 def get_case(self, file_path): 9 cases = [] # 存放所有的測試用例 10 if file_path.endswith(‘.xls‘) or file_path.endswith(‘.xlsx‘): # 判斷路徑是否存在 11 try: 12 book = xlrd.open_workbook(file_path) 13 sheet = book.sheet_by_index(0) # 打開用例文件 14 for i in range(1, sheet.nrows): # 從第二行開始遍歷excel文件內容(第一行是標題) 15 row_data = sheet.row_values(i) # 獲取每行內容 16 cases.append(row_data[4:8]) # 在cases這個list中存每個用例的url,method,req_data,check 17 apt_log.info(‘共讀取%s條用例‘ % (len(cases))) # 檢查cases中的元素個數,日誌記錄讀取了幾條用例 18 self.file_path = file_path # 既然讀取成功說明這個文件路徑是正確的,那麽這邊定義下面寫exccel就可以直接使用了 19 except Exception as e: 20 apt_log.error(‘【%s】用例打開失敗,錯誤信息:%s‘ % (file_path, e)) 21 else: 22 apt_log.error(‘用例文件不合法,%s‘ % file_path) 23 return cases 24 25 def dataToDict(self, data): # 將用例中的req_data轉為字典格式,可以直接用在request模塊 26 res = {} 27 data = data.split(‘,‘) # 這個地方要求用例中請求參數使用英文逗號分割的 28 # 這邊分割入參後,入參變為[‘a=1‘, ‘b=2‘]這樣的格式 29 for d in data: 30 k, v = d.split(‘=‘) 31 # 再次分割後變為[‘a‘,‘1‘]這樣的模式分別用k代表a,v代表1 32 res[k] = v # 存入字典中變成‘a‘:1,這樣的模式可直接在request模塊接口測試中作為入參使用 33 return res 34 35 def my_request(self, url, method, data): 36 method = method.upper() # 首先將請求方式變為大寫模式,方便後面驗證 37 data = self.dataToDict(data) # 把a=1,b=2格式的請求參數變成字典格式 38 try: 39 if method == ‘POST‘: 40 res = requests.post(url, data).text # 如果請求方式是post按照post模式進行接口測試 41 elif method == ‘GET‘: 42 res = requests.get(url, data).text # 按照get方式傳入url和data進行接口測試 43 else: 44 apt_log.warning(‘暫不支持該請求‘) # 其他的請求方式不支持,打印日誌並返回提示 45 res = ‘暫不支持該請求‘ 46 except Exception as e: 47 msg = ‘【%s】接口調用失敗,%s‘ % (url, e) # 請求未成功提示接口調用失敗,寫入日誌並返回提示 48 apt_log.error(msg) 49 res = msg 50 return res 51 52 def check_res(self, res, check): 53 res.replace(‘": "‘, ‘=‘).replace(‘": ‘, ‘=‘) # 返回的報文是json格式的,利用字符替換讓數據變成"a=1,b=2"的格式 54 for c in check.split(‘,‘): # 判斷驗證數據是否在返回的報文中 55 if c not in res: 56 apt_log.info(‘結果校驗失敗,預期結果:【%s】,實際結果【%s】‘ % (c, res)) # 不匹配則測試校驗失敗,打印日誌 57 return ‘失敗‘ # 返回失敗的提示 58 return ‘通過‘ # 如果存在說明測試通過 59 60 def write_excel(self, cases_res): # 入參是每個用例的執行結果 61 book = xlrd.open_workbook(self.file_path) 62 new_book = copy.copy(book) 63 sheet = new_book.get_sheet(0) # 復制測試用例excel文件 64 row = 1 65 for case_res in cases_res: # 遍歷寫入數據 66 sheet.write(row, 8, case_res[0]) # 第八列寫返回結果 67 sheet.write(row, 9, case_res[1]) # 第九列寫測試是否通過 68 row += 1 69 new_book.save(self.file_path.replace(‘xlsx‘, ‘xls‘)) # 保存結果 70
5、start文件
啟動文件,用於集成所有的模塊完成目標。
1 import os 2 import sys 3 from lib.common import OpCase 4 from lib.send_emile import sendemile 5 from config import setting 6 7 BASE_PATH = os.path.dirname( 8 os.path.dirname(os.path.abspath(__file__)) 9 ) # 找到APT這個文件夾的地址 10 sys.path.insert(0, BASE_PATH) # 把ATP目錄加到環境變量中,用於在其他不能幫忙加環境變量的時候 11 12 13 class CaseRun(object): 14 def find_cases(self): 15 op = OpCase() # 實例化了操作用例這個類 16 for f in os.listdir(setting.CASE_PATH): # 獲取到cases文件夾下的文件 17 abs_path = os.path.join(setting.CASE_PATH, f) # 拼接測試用例文件的絕對路徑 18 case_list = op.get_case(abs_path) # 利用get_case函數獲取到每個用例中的case 19 res_list = [] # 創建一個空的list來存放測試返回的報文和測試結果 20 pass_count = 0 # 用來計算成功用例個數 21 fail_count = 0 # 用來計算失敗用例格式 22 for case in case_list: 23 url, method, req_data, check = case # get_case函數中提取每行用例的四個元素,分別定義一下 24 res = op.my_request(url, method, req_data) # 調用my_request函數進行測試接口返回結果 25 status = op.check_res(res, check) # 檢查測試返回報文是否和預計測試結果相同,如果相同測試通過,否則測試失敗 26 res_list.append([res, status]) # 為了一次性寫入測試結果,先將結果放入list中 27 if status == ‘通過‘: 28 pass_count += 1 29 else: 30 fail_count += 1 31 op.write_excel(res_list) # 寫入excel 32 msg = ‘‘‘ # 定義郵件正文 33 XX你好: 34 本次共運行%s條用例,通過%s條,失敗%s條。 35 ‘‘‘ % (len(res_list), pass_count, fail_count) 36 sendemile(‘測試用例運行結果‘, content=msg, attrs=abs_path) # 利用sendmail函數發送郵件,入參分別是主題,內容和附件 37 38 39 CaseRun().find_cases() # 運行find_cases函數
接口測試學習-python第八課(數據驅動測試)