一、说明
该接口自动化测试时基于python+requests库+excel进行实现的,没有选用python+requests+uniitest+htmltestrunner或者python+requests+pytest+htmltestrunner框架:这两个框架的好处整个框架结构全部都封装好了,只需要往里面添加业务逻辑即接口测试py文件即可,但是有个致命的缺陷,就是测试用例的易维护性不是很好,当接口发生变化,就要去直接修改业务逻辑的py文件,而且测试数据都是写死在每一个函数中,或者持久化在数据库中,需要直接修改py文件,所以就没有才这两个框架,只选取了其中必要的组成部分:python+requests,然后自己完成后续业务逻辑;
二、接口测试框架的拆解
现有框架是根据HTTP请求的请求、响应的生命周期来进行规划框架的目录结构的;
1、HTTP请求的生命周期
1.1、建立连接;
1.2、接收请求;
1.3、处理请求;
1.4、访问资源;
1.5、构建响应;
1.6、发送响应;
1.7、记录事务处理过程;
2、框架目录结构
2.1、base包:封装请求方法
base包下new_test.py文件,主要用于封装常规的请求方法;
http请求方式中主要有8种常见的请求方式:GET,POST,HEAD,OPTIONS,PUT,DELETE,TRACE,CONNECT方法,这几种请求方式详细使用方式请自行百度;
我只封装了其中最常见的四种方式:GET,POST,DELETE,PUT方式,因为项目中只用到了这四种方式;
new_test.py:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 3 import requests,json 4 ##原主程序:将data及headers的为空的情况考虑进去,就会报错404 5 class Runmethod: 6 ###get方法不会有data,查询参数都是跟在url后面的;需要后再进行优化; 7 def getmain(self,url,data=None,headers=None): 8 res = None 9 if headers !=None: ####正常的get请求; 10 if data == None: 11 res = requests.get(url=url, headers=headers) 12 else: 13 res = requests.get(url=url, data=data, headers=headers) 14 15 else: ##非常规的get请求,如本身是get请求,为了保证数据的安全性直接使用get方法,将原本卸载url中的参数全部写在data里面; 16 if data == None: 17 res = requests.get(url=url) 18 else: 19 res = requests.get(url=url, data=data) 20 return res 21 22 def postmain(self,url,data=None,headers=None): 23 res = None 24 if headers !=None: ####正常的post请求; 25 if data ==None: 26 res = requests.post(url=url,headers=headers) 27 else: 28 res = requests.post(url=url, data=data, headers=headers) 29 else: ##非常规的post请求,如本身是get请求,为了保证数据的安全性直接使用post方法,将原本卸载url中的参数全部写在data里面; 30 if data == None: 31 res = requests.post(url=url) 32 else: 33 res = requests.post(url=url,data=data) 34 return res 35 def runmain(self,method,url,data=None,headers=None): 36 res = None 37 if method == "GET": 38 res = self.getmain(url,data=None,headers=None) 39 elif method == "POST": 40 res = self.postmain(url,data=None,headers=None) 41 return res 42 ##测试类:只考虑正常情况,不考虑空值, 43 class Runmethod2: 44 def getmain(self,url,data,headers): 45 res = requests.get(url=url, data=data, headers=headers) 46 return res 47 def postmain(self,url,data,headers): 48 res = requests.post(url=url, data=data, headers=headers) 49 return res 50 def runmain(self,method,url,data,headers): 51 res = None 52 if method == "GET": 53 res = self.getmain(url, data, headers) 54 elif method == "POST": 55 res = self.postmain(url, data, headers) 56 return res 57 58 ##只考虑data是否是未空,前两种方式在调试过程中有问题; 59 class Runmethod3: 60 ###get请求方式 61 def getmain(self,url,headers = None): 62 res = None 63 if headers !=None: 64 res = requests.get(url=url,headers = headers) 65 else: 66 res = requests.get(url=url) 67 return res.json() 68 ##post请求方式 69 def postmain(self,url,data=None,headers=None): 70 res = None 71 if headers != None: 72 res = requests.post(url=url,data=data, headers=headers) 73 else: 74 res = requests.post(url=url,data=data) 75 return res.json() 76 def putmain(self,url,data=None,headers =None): 77 res = None 78 if headers != None: 79 res = requests.post(url=url, data=data, headers=headers) 80 else: 81 res = requests.post(url=url, data=data) 82 return res.json() 83 def deletemain(self,url,data=None,headers = None): 84 res = None 85 if headers != None: 86 res = requests.delete(url=url,data = data, headers=headers) 87 else: 88 res = requests.delete(url=url, data=data) 89 return res.json() 90 91 def runmain(self,method,url,data=None,headers=None): 92 res = None 93 if method == "GET": 94 res = self.getmain(url,headers = headers) 95 elif method == "POST": 96 res = self.postmain(url, data=data, headers=headers) 97 # return json.dumps(res,indent=2,ensure_ascii=False) 98 elif method == "PUT": 99 res = self.putmain(url,data=data,headers=headers) 100 print(type(res)) 101 elif method == "DELETE": 102 res = self.deletemain(url,data=data,headers=headers) 103 return json.dumps(res,indent=2,ensure_ascii=False)