python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告
生活随笔
收集整理的這篇文章主要介紹了
python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.環境準備:
- python3.6
- requests
- xlrd
- openpyxl
- HTMLTestRunner_api
2.目前實現的功能:
- 封裝requests請求方法
- 在excel填寫接口請求參數
- 運行完后,重新生成一個excel報告,結果寫入excel
- 用unittest+ddt數據驅動模式執行
- HTMLTestRunner生成可視化的html報告
- 對于沒有關聯的單個接口請求是可以批量執行的,需要登錄的話寫到setUpclass里的session里保持cookies
- token關聯的不能實現
- logging日志文件暫時未加入
3.目前已知的缺陷:
- 無法實現參數關聯:上個請求的結果是下個請求的參數,如token
- 接口請求參數名有重復的,目前未處理,如key1=value1&key1=value2,兩個key都一樣,這種需要用元組存儲,目前暫時未判斷
- 生成的excel樣式未處理,后期慢慢優化樣式
- python新手可能遇到模塊導入報錯問題
項目結構
excel測試數據
xlrd讀excel數據
1.先從excel里面讀取測試數據,返回字典格式
1 # coding:utf-82 3 # 作者:上海-悠悠4 # QQ群:2262967435 6 import xlrd7 class ExcelUtil():8 def __init__(self, excelPath, sheetName="Sheet1"):9 self.data = xlrd.open_workbook(excelPath) 10 self.table = self.data.sheet_by_name(sheetName) 11 # 獲取第一行作為key值 12 self.keys = self.table.row_values(0) 13 # 獲取總行數 14 self.rowNum = self.table.nrows 15 # 獲取總列數 16 self.colNum = self.table.ncols 17 18 def dict_data(self): 19 if self.rowNum <= 1: 20 print("總行數小于1") 21 else: 22 r = [] 23 j = 1 24 for i in list(range(self.rowNum-1)): 25 s = {} 26 # 從第二行取對應values值 27 s['rowNum'] = i+2 28 values = self.table.row_values(j) 29 for x in list(range(self.colNum)): 30 s[self.keys[x]] = values[x] 31 r.append(s) 32 j += 1 33 return r 34 35 if __name__ == "__main__": 36 filepath = "debug_api.xlsx" 37 sheetName = "Sheet1" 38 data = ExcelUtil(filepath, sheetName) 39 print(data.dict_data()) 40 openpyxl寫入數據 41 42 1.再封裝一個寫入excel數據的方法 43 44 # coding:utf-8 45 from openpyxl import load_workbook 46 import openpyxl 47 48 # 作者:上海-悠悠 49 # QQ群:226296743 50 51 def copy_excel(excelpath1, excelpath2): 52 '''復制excek,把excelpath1數據復制到excelpath2''' 53 wb2 = openpyxl.Workbook() 54 wb2.save(excelpath2) 55 # 讀取數據 56 wb1 = openpyxl.load_workbook(excelpath1) 57 wb2 = openpyxl.load_workbook(excelpath2) 58 sheets1 = wb1.sheetnames 59 sheets2 = wb2.sheetnames 60 sheet1 = wb1[sheets1[0]] 61 sheet2 = wb2[sheets2[0]] 62 max_row = sheet1.max_row # 最大行數 63 max_column = sheet1.max_column # 最大列數 64 65 for m in list(range(1,max_row+1)): 66 for n in list(range(97,97+max_column)): # chr(97)='a' 67 n = chr(n) # ASCII字符 68 i ='%s%d'% (n, m) # 單元格編號 69 cell1 = sheet1[i].value # 獲取data單元格數據 70 sheet2[i].value = cell1 # 賦值到test單元格 71 72 wb2.save(excelpath2) # 保存數據 73 wb1.close() # 關閉excel 74 wb2.close() 75 76 class Write_excel(object): 77 '''修改excel數據''' 78 def __init__(self, filename): 79 self.filename = filename 80 self.wb = load_workbook(self.filename) 81 self.ws = self.wb.active # 激活sheet 82 83 def write(self, row_n, col_n, value): 84 '''寫入數據,如(2,3,"hello"),第二行第三列寫入數據"hello"''' 85 self.ws.cell(row_n, col_n).value = value 86 self.wb.save(self.filename) 87 88 if __name__ == "__main__": 89 copy_excel("debug_api.xlsx", "testreport.xlsx") 90 wt = Write_excel("testreport.xlsx") 91 wt.write(4, 5, "HELLEOP") 92 wt.write(4, 6, "HELLEOP")?
封裝request請求方法
1.把從excel讀處理的數據作為請求參數,封裝requests請求方法,傳入請求參數,并返回結果
2.為了不污染測試的數據,出報告的時候先將測試的excel復制都應該新的excel
3.把測試返回的結果,在新的excel里面寫入數據
1 # coding:utf-82 import json3 import requests4 from excelddtdriver.common.readexcel import ExcelUtil5 from excelddtdriver.common.writeexcel import copy_excel, Write_excel6 7 # 作者:上海-悠悠8 # QQ群:2262967439 10 11 def send_requests(s, testdata): 12 '''封裝requests請求''' 13 method = testdata["method"] 14 url = testdata["url"] 15 # url后面的params參數 16 try: 17 params = eval(testdata["params"]) 18 except: 19 params = None 20 # 請求頭部headers 21 try: 22 headers = eval(testdata["headers"]) 23 print("請求頭部:%s" % headers) 24 except: 25 headers = None 26 # post請求body類型 27 type = testdata["type"] 28 29 test_nub = testdata['id'] 30 print("*******正在執行用例:----- %s ----**********" % test_nub) 31 print("請求方式:%s, 請求url:%s" % (method, url)) 32 print("請求params:%s" % params) 33 34 # post請求body內容 35 try: 36 bodydata = eval(testdata["body"]) 37 except: 38 bodydata = {} 39 40 # 判斷傳data數據還是json 41 if type == "data": 42 body = bodydata 43 elif type == "json": 44 body = json.dumps(bodydata) 45 else: 46 body = bodydata 47 if method == "post": print("post請求body類型為:%s ,body內容為:%s" % (type, body)) 48 49 verify = False 50 res = {} # 接受返回數據 51 52 try: 53 r = s.request(method=method, 54 url=url, 55 params=params, 56 headers=headers, 57 data=body, 58 verify=verify 59 ) 60 print("頁面返回信息:%s" % r.content.decode("utf-8")) 61 res['id'] = testdata['id'] 62 res['rowNum'] = testdata['rowNum'] 63 res["statuscode"] = str(r.status_code) # 狀態碼轉成str 64 res["text"] = r.content.decode("utf-8") 65 res["times"] = str(r.elapsed.total_seconds()) # 接口請求時間轉str 66 if res["statuscode"] != "200": 67 res["error"] = res["text"] 68 else: 69 res["error"] = "" 70 res["msg"] = "" 71 if testdata["checkpoint"] in res["text"]: 72 res["result"] = "pass" 73 print("用例測試結果: %s---->%s" % (test_nub, res["result"])) 74 else: 75 res["result"] = "fail" 76 return res 77 except Exception as msg: 78 res["msg"] = str(msg) 79 return res 80 81 def wirte_result(result, filename="result.xlsx"): 82 # 返回結果的行數row_nub 83 row_nub = result['rowNum'] 84 # 寫入statuscode 85 wt = Write_excel(filename) 86 wt.write(row_nub, 8, result['statuscode']) # 寫入返回狀態碼statuscode,第8列 87 wt.write(row_nub, 9, result['times']) # 耗時 88 wt.write(row_nub, 10, result['error']) # 狀態碼非200時的返回信息 89 wt.write(row_nub, 12, result['result']) # 測試結果 pass 還是fail 90 wt.write(row_nub, 13, result['msg']) # 拋異常 91 92 if __name__ == "__main__": 93 data = ExcelUtil("debug_api.xlsx").dict_data() 94 print(data[0]) 95 s = requests.session() 96 res = send_requests(s, data[0]) 97 copy_excel("debug_api.xlsx", "result.xlsx") 98 wirte_result(res, filename="result.xlsx")?
測試用例unittest+ddt
1.測試用例用unittest框架組建,并用ddt數據驅動模式,批量執行用例
1 # coding:utf-82 import unittest3 import ddt4 import os5 import requests6 from excelddtdriver.common import base_api7 from excelddtdriver.common import readexcel8 from excelddtdriver.common import writeexcel9 10 # 作者:上海-悠悠 11 # QQ群:226296743 12 13 # 獲取demo_api.xlsx路徑 14 curpath = os.path.dirname(os.path.realpath(__file__)) 15 testxlsx = os.path.join(curpath, "demo_api.xlsx") 16 17 # 復制demo_api.xlsx文件到report下 18 report_path = os.path.join(os.path.dirname(curpath), "report") 19 reportxlsx = os.path.join(report_path, "result.xlsx") 20 21 testdata = readexcel.ExcelUtil(testxlsx).dict_data() 22 @ddt.ddt 23 class Test_api(unittest.TestCase): 24 @classmethod 25 def setUpClass(cls): 26 cls.s = requests.session() 27 # 如果有登錄的話,就在這里先登錄了 28 writeexcel.copy_excel(testxlsx, reportxlsx) # 復制xlsx 29 30 @ddt.data(*testdata) 31 def test_api(self, data): 32 # 先復制excel數據到report 33 res = base_api.send_requests(self.s, data) 34 35 base_api.wirte_result(res, filename=reportxlsx) 36 # 檢查點 checkpoint 37 check = data["checkpoint"] 38 print("檢查點->:%s"%check) 39 # 返回結果 40 res_text = res["text"] 41 print("返回實際結果->:%s"%res_text) 42 # 斷言 43 self.assertTrue(check in res_text) 44 45 if __name__ == "__main__": 46 unittest.main()?
生成報告
1.用HTMLTestRunner生成html報告,我這里改了下名稱,改成了HTMLTestRunner_api.py
此文件跟selenium的報告是通用的,github可下載https://github.com/yoyoketang/selenium_report/tree/master/selenium_report
?
2.生成的excel報告
3.生成的html報告
總結
以上是生活随笔為你收集整理的python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 再话单元测试unittest
- 下一篇: unittest+discover批量处