python 数据驱动接口自动化框架_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新手可能遇到模块导入报错问题

项目结构

python 数据驱动接口自动化框架_python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告..._第1张图片

excel测试数据

python 数据驱动接口自动化框架_python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告..._第2张图片

xlrd读excel数据

1.先从excel里面读取测试数据,返回字典格式

python 数据驱动接口自动化框架_python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告..._第3张图片

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报告

python 数据驱动接口自动化框架_python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告..._第4张图片

3.生成的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+requests+excel接口测试

2018-06-14   17:00:13 环境准备: - Python 3.7 - requests库 - xlrd 1.创建Excel文件 2.读取Excel文件 import xlrd clas ...

随机推荐

Django框架初入

一.Django 特性 数据库功能强大(利用python的类继承,几行代码就可以实现一个动态的数据库操作接口(API)) 强大的后台功能 优雅的网址(正则匹配网址,传递到对应函数) 模板与缓存系统 二 ...

Centos5.8 安装open

安装openssl 和 openssl-devel, 建议使用最新版本, 编译安装 yum install gcc-c++ wget http://www.openssl.org/source/ope ...

DF与EF的区别

DF:专有文件 EF:基本文件 1.EF没有文件名,只有FID(文件标识符) 2.DF有文件名,又有FID,因此COS可以根据文件名来访问DF

浅析StackTrace【转】

我们在学习函数调用时,都知道每个函数都拥有自己的栈空间.一个函数被调用时,就创建一个新的栈空间.那么通过函数的嵌套调用最后就形成了一个函数调用堆栈.在c#中,使用StackTrace记录这个堆栈.你可 ...

[C++]现行的试卷封面并获取学生题目得分信息以及学号信息的原型系统

大二的时候写的一个CV小玩意,最终决定还是把它放出来,也许会帮助到很多人,代码写的很丑,大家多多包涵.附加实验报告主要部分. 课题背景及意义: 本项目主要目标是设计一套能自动分析我校现行的试卷封面并获 ...

Python爬虫入门 Urllib库的基本使用

1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS.CSS ...

mysql中group by和order by同时使用无效的替代方案

前言 最近一年由于工作需要大部分使用的都是NoSql数据库,对关系型数据库感觉越来越陌生,一个由group by和order by 引发的血案由此而生.在此做个记录,以备不时之需. 需求 首先,看一下 ...

高级shell 脚本

1.函数 函数是一个脚本代码块,你可以为其命名并在代码中任何位置重用.要在脚本中使用该代码块时,只要使用所起的函数名就行了(这个过程称为调用函数).本节将会介绍如何在shell脚本中创建和使用函数 创 ...

git遇到的问题 .Git: There is no tracking information for the current branch.

1.Git: There is no tracking information for the current branch. 在执行git pull的时候,提示当前branch没有跟踪信息: git ...

关于CSS3的filter(滤镜) 属性

修改所有图片或者元素的颜色为黑白 (100% 灰度) DOM{ -webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */ filter: ...

你可能感兴趣的:(python,数据驱动接口自动化框架)