數據驅動之 python + requests + Excel


數據驅動

是根據數據來測試的,如讀取 excel表中的測試用例自動填寫測試結果,發送測試報告
包括以下模塊:
  • 1.獲取用例
  • 2.調用接口
  • 3.校驗結果
  • 4.發送測試報告
  • 5.異常處理
  • 6.日志模塊

1. 首先設計好測試用例

2.建立文件結構

該自動化測試框架命名為:ATP,bin目錄下寫主程序,cases目錄下放測試用例,conf目錄下放配置文件,lib目錄下放各個封裝好的模塊,logs目錄下放日志文件,和readme文件。

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:封裝發送郵件模塊

 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.py

 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 程序,收到郵件內容如下:

 

 

 

 

 

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM