數據驅動
是根據數據來測試的,如讀取 excel表中的測試用例自動填寫測試結果,發送測試報告
包括如下模塊:
- 1.獲取用例
- 2.調用接口
- 3.校驗結果
- 4.發送測試報告
- 5.異常處理
- 6.日誌模塊
1. 首先設計好測試用例
2.創建文件結構
該自動化測試框架命名爲:ATP,bin目錄下寫主程序,cases目錄下放測試用例,conf目錄下放配置文件,lib目錄下放各個封裝好的模塊,logs目錄下放日誌文件,和readme文件。app
3.封裝模塊
common.py:封裝讀取excel用例、調用接口、檢驗結果、寫入報告這幾個模塊。框架
1 """ 2 第一步:讀取excel中用例 3 第二步:根據用例發送請求 4 第三步:校驗結果 5 第四步:將測試結果、返回報文寫入excel 6 """ 7 import xlrd,requests 8 from xlutils import copy 9 from lib.log import atp_log 10 11 class OpCase(object): 12 def get_case(self,file_path): 13 cases= [] #定義一個列表存放全部的cases 14 if file_path.endswith('.xls') or file_path.endswith('.xlsx'): 15 try: 16 book = xlrd.open_workbook(file_path) 17 sheet = book.sheet_by_index(0) 18 for i in range(1,sheet.nrows): 19 row_data = sheet.row_values(i) #獲取的每一行數據存到列表row_data 20 cases.append(row_data[4:8]) 21 atp_log.info('共讀取%s條用例'%(len(cases))) 22 self.file_path = file_path #由於該函數已經傳了參數路徑,爲方便write_excel引用,在此實例化 23 except Exception as e: 24 atp_log.error('[%s]用例獲取失敗,錯誤信息:%s'%(file_path,e)) 25 else: 26 atp_log.error('用例文件不合法,%s'%file_path) 27 return cases 28 def my_request(self,url,method,data): 29 data = self.dataToDict(data) 30 try: 31 if method.upper() == 'POST': 32 res = requests.post(url,data).text 33 elif method.uper() == 'GET': 34 res = requests.get(url,params=data).text 35 else: 36 atp_log.warning('該請求方式暫不支持') 37 res = '該請求方式暫不支持' 38 except Exception as e: 39 msg = '【%s】接口調用失敗,%s'%(url,e) 40 atp_log.error(msg) 41 res = msg 42 return res 43 def dataToDict(self,data): #把數據轉成字典。 44 res = {} 45 data = data.split(',') 46 for d in data: # 47 k, v = d.split('=') 48 res[k] = v 49 def check_res(self,res,check): #res:實際結果,check:預期結果 50 res = res.replace('": "','=').replace('": ','=') 51 for c in check.split(','): 52 if c not in res: 53 atp_log.info('結果校驗失敗,預期結果:【%s】,實際結果【%s】'%(c,res)) 54 return '失敗' 55 return '成功' 56 def write_excel(self,case_res): 57 book = xlrd.open_workbook(self.file_path) 58 new_book = copy.copy(book) 59 sheet = new_book.get_sheet(0) 60 row = 1 61 for case_case in case_res: 62 sheet.write(row,8,case_case[0]) 63 sheet.write(row,9,case_case[1]) 64 row += 1 65 new_book.save(self.file_path.replace('xlsx','xls'))
log.py:封裝日誌模塊函數
1 import logging,os 2 from logging import handlers 3 from conf import setting 4 class Mylogger(): 5 def __init__(self,file_name,level='info',backCount=5,when='D'): 6 logger = logging.getLogger() # 先實例化一個logger對象,先建立一個辦公室 7 logger.setLevel(self.get_level(level)) # 設置日誌的級別 8 # f1 = logging.FileHandler(filename='a.log',mode='a',encoding='utf-8') #找到寫日誌文件的這我的 9 c1 = logging.StreamHandler() # 負責往控制檯輸出的 10 b1 = handlers.TimedRotatingFileHandler(filename=file_name, when=when, interval=1, backupCount=backCount, encoding='utf-8') 11 fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') 12 c1.setFormatter(fmt) 13 b1.setFormatter(fmt) 14 logger.addHandler(c1) 15 logger.addHandler(b1) 16 self.logger = logger 17 def get_level(self,str): 18 level = { 19 'debug':logging.DEBUG, 20 'info':logging.INFO, 21 'warm':logging.WARNING, 22 'error':logging.ERROR 23 } 24 str = str.lower() 25 return level.get(str) 26 27 path = os.path.join(setting.LOG_PATH,setting.LOG_NAME) 28 atp_log = Mylogger(path,'debug').logger 29 #直接在這裏實例化,用的時候不用再實例化了 30 #別的地方用的時候,直接atp_log.warnning('xxxx')
send_mail.py:封裝發送郵件模塊post
1 import yagmail 2 from conf import setting 3 from lib.log import atp_log 4 def sendmail(title,content,attrs=None): 5 m = yagmail.SMTP(host=setting.MAIL_HOST,user=setting.MAIL_USER, 6 password=setting.MAIL_PASSWRD,smtp_ssl=True) 7 m.send(to=setting.TO, 8 subject=title, 9 contents = content, 10 attachments = attrs) 11 atp_log.info('發送郵件完成')
4.配置文件
setting.py,配置文件:設置郵件地址、日誌默認級別、用例存放路徑、日誌存放路徑、日誌文件名測試
1 import os 2 BASE_PATH = os.path.dirname( 3 os.path.dirname(os.path.abspath(__file__)) 4 ) #三層目錄定位到ATP目錄 5 MAIL_HOST = 'smtp.qq.com' 6 MAIL_USER='12*****89@qq.com' 7 MAIL_PASSWRD = 'gjn*****bcgh' 8 TO = [ 9 '12*****9@qq.com' 10 ] 11 LEVEL = 'debug' #設置日誌默認級別 12 13 LOG_PATH = os.path.join(BASE_PATH,'logs') #日誌文件在logs目錄下 14 CASE_PATH = os.path.join(BASE_PATH,'cases') #用例文件在cases目錄下 15 LOG_NAME = 'atp_log' #設置日誌文件名
5.將ATP文件Mark directory as Sources Root
6.編寫主程序
start.pyurl
1 import os,sys 2 BASE_PATH = os.path.dirname( 3 os.path.dirname(os.path.abspath(__file__)) 4 ) 5 sys.path.insert(0,BASE_PATH) 6 7 from lib.common import OpCase 8 from lib.send_mail import sendmail 9 from conf import setting 10 class CaseRun(object): 11 def find_case(self): 12 op = OpCase() 13 for f in os.listdir(setting.CASE_PATH): #每次循環的時候讀一個excel 14 abs_path = os.path.join(setting.CASE_PATH,f) 15 case_list = op.get_case(abs_path) 16 res_list = [] 17 pass_count,fail_count= 0,0 18 for case in case_list: #循環每個excel裏面的全部用例 19 url,method,req_data,check = case 20 res = op.my_request(url,method,req_data) #調用完接口返回的結果 21 status = op.check_res(res,check) 22 res_list.append([res,status]) 23 if status == '經過': 24 pass_count += 1 25 else: 26 fail_count += 1 27 op.write_excel(res_list) 28 msg = ''' 29 xx你好, 30 本次共運行%s條用例,經過%s條,失敗%s條。 31 '''%(len(res_list),pass_count,fail_count) 32 sendmail('測試用例運行結果',content=msg,attrs=abs_path) 33 34 CaseRun().find_case()
OK,數據驅動自動化測試框架編寫完成,運行 start.py 程序,收到郵件內容以下:spa