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-8
2
3 # 作者:上海-悠悠
4 # QQ群:226296743
5
6 import xlrd
7 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-8
2 import json
3 import requests
4 from excelddtdriver.common.readexcel import ExcelUtil
5 from excelddtdriver.common.writeexcel import copy_excel, Write_excel
6
7 # 作者:上海-悠悠
8 # QQ群:226296743
9
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"] != "":
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-8
2 import unittest
3 import ddt
4 import os
5 import requests
6 from excelddtdriver.common import base_api
7 from excelddtdriver.common import readexcel
8 from excelddtdriver.common import writeexcel
9
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
1 # coding=utf-8
2 import unittest
3 import time
4 from excelddtdriver.common import HTMLTestRunner_api
5 import os
6
7 # 作者:上海-悠悠
8 # QQ群:226296743
9
10 curpath = os.path.dirname(os.path.realpath(__file__))
11 report_path = os.path.join(curpath, "report")
12 if not os.path.exists(report_path): os.mkdir(report_path)
13 case_path = os.path.join(curpath, "case")
14
15 def add_case(casepath=case_path, rule="test*.py"):
16 '''加载所有的测试用例'''
17 # 定义discover方法的参数
18 discover = unittest.defaultTestLoader.discover(casepath,
19 pattern=rule,)
20
21 return discover
22
23 def run_case(all_case, reportpath=report_path):
24 '''执行所有的用例, 并把结果写入测试报告'''
25 htmlreport = reportpath+r"\result.html"
26 print("测试报告生成地址:%s"% htmlreport)
27 fp = open(htmlreport, "wb")
28 runner = HTMLTestRunner_api.H全部折叠 折叠标题:
29
30 显示行号 行内代码
31 TMLTestRunner(stream=fp,
32 verbosity=2,
33 title="测试报告",
34 description="用例执行情况")
35
36 # 调用add_case函数返回值
37 runner.run(all_case)
38 fp.close()
39
40 if __name__ == "__main__":
41 cases = add_case()
42 run_case(cases)
2.生成的excel报告
3.生成的html报告
python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告的更多相关文章
- python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告(二)
可以参考 python+requests接口自动化完整项目设计源码(一)https://www.cnblogs.com/111testing/p/9612671.html 原文地址https://ww ...
- python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告(已弃用)
前言 1.环境准备: python3.6 requests xlrd openpyxl HTMLTestRunner_api 2.目前实现的功能: 封装requests请求方法 在excel填写接口请 ...
- Python+Selenium+Unittest+Ddt+HTMLReport分布式数据驱动自动化测试框架结构
1.Business:公共业务模块,如登录模块,可以把登录模块进行封装供调用 ------login_business.py from Page_Object.Common_Page.login_pa ...
- Python+Pytest+Allure+Git+Jenkins接口自动化框架
Python+Pytest+Allure+Git+Jenkins接口自动化框架 一.接口基础 接口测试是对系统和组件之间的接口进行测试,主要是效验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系. ...
- Python——Requests库的开发者接口
本文介绍 Python Requests 库的开发者接口,主要内容包括: 目录 一.主要接口 1. requests.request() 2. requests.head().get().post() ...
- python+ddt+unittest+excel+request实现接口自动化
接口自动化测试流程:需求分析-用例设计--脚本开发--测试执行--结果分析1.获取接口文档,根据文档获取请求方式,传输协议,请求参数,响应参数,判断测试是否通过设计用例2.脚本开发:使用request ...
- python+requests+excel 接口自动化框架
一.项目框架如图: 1.common :这个包都是一些公共的方法,如:手机号加解密,get/post接口请求的方法封装,接口鉴权,发邮件,读写excel文件方法等等 2.result:存放每次运行的l ...
- Python接口自动化测试框架: pytest+allure+jsonpath+requests+excel实现的接口自动化测试框架(学习成果)
废话 最近在自己学习接口自动化测试,这里也算是完成一个小的成果,欢迎大家交流指出不合适的地方,源码在文末 问题 整体代码结构优化未实现,导致最终测试时间变长,其他工具单接口测试只需要39ms,该框架中 ...
- Python+requests+excel接口测试
2018-06-14 17:00:13 环境准备: - Python 3.7 - requests库 - xlrd 1.创建Excel文件 2.读取Excel文件 import xlrd clas ...
随机推荐
- 学习:ups电池放电时间是怎么计算的?
例如现有20KVA的UPS一台,负载功率为8000W,电池节数为64节,容量为32AH,电池电压为12V,那么UPS电源的放电时间计算方法如下: 负载功率*放电时长=电池放电量*电池电压*逆变率 80 ...
- [转]decorator(HTML装饰器)
原文地址:https://blog.csdn.net/jzh440/article/details/7770013 1>:每当遇到一个新的技术,首先我会问自己,这个技术是做神马的?用这个技术有神 ...
- MATLAB 显示输出数据的三种方式
MATLAB 显示输出数据的三种方式 ,转载 https://blog.csdn.net/qq_35318838/article/details/78780412 1.改变数据格式 当数据重复再命令行 ...
- (转)x264的一些参数设置对编码效率的影响
转自:http://www.cnblogs.com/wainiwann/p/5647521.html i_luma_deadzone[0]和i_luma_deadzone[1]分别对应inter和in ...
- openwrt官方固件怎么中继网络
关键一点,取消勾
- nodejs在windows下的安装配置(使用NVM的方式)
NVM的安装 1.下载安装包,https://github.com/coreybutler/nvm-windows/releases 2.下载完成后点击nvm-setup,按步骤安装,注意路径中不能带 ...
- iOS学习之--字符串的删除替换(字符串的常用处理,删除,替换)
字符串操作,比较简单,仅做记录! 1.删除 NSString *str1 = @"<hello,wo r d!>"; //删除字符串两端的尖括号 NSMutableSt ...
- 使用PHP几种写99乘法表的方式
首先按照规矩,还是先废话一番,对于刚学PHP的新手来讲,用php写九九乘法表无疑是非常经典的一道练习题. 但不要小看这道练习题,它对于逻辑的考验还是相当到位的. 也许有人会觉得,九九乘法表有什么难的, ...
- 【Zookeeper系列】zookeeper面试题(转)
原文链接:https://segmentfault.com/a/1190000014479433 1.ZooKeeper是什么? ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是 ...
- Docker学习笔记之二:制作镜像并PUSH
Pull 如果是Public的(docker官方仓库和加速器) 直接 docker pull ubuntu:16.04 即可 若是私有的 首先登陆 docker login 仓库Host 之后 doc ...