1、通过Unittest实现用例的组织和执行,requests库实现接口测试。 2、目的:以云平台为例(http://www.nlecloud.com)实现注册、登录、更新APIKey、新增项目、新增设备、新增传感器、新增执行器、删除项目的接口自动化测试,并断言每条用例是否执行成功。
(1)安装requests、json、ddt、xlrd包,通过pip install xxx的方式。
(1) 在dataconfig文件下创建NLE.xlsx,内容如下所示:
(1)新建http_method.py文件封装requests基本方法
#coding=utf8 import requests,json class Method: #post、put、delete封装 #注意:get如果不传data的话,注意写先定义好data=None,然后注意参数顺序,data=None放在最后的位置。 def send_request(self,url,method,headers,data=None): if (type(headers) == str): headers = json.loads(headers) if (type(data) == dict): data = json.dumps(data) res_str = None if method == "post": res_str = requests.post(url=url,headers=headers,data=data) elif method == "put": res_str = requests.put(url=url,headers=headers,data=data) else: res_str = requests.delete(url=url,headers=headers,data=data) res_dict = json.loads(res_str.content) return res_dict(2)创建path_config.py来定义路径
import os BASE_PATH = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0] print(BASE_PATH) FILE_PATH = os.path.join(BASE_PATH, 'dataconfig','NLE.xlsx') TEST_PATH = os.path.join(BASE_PATH, 'test') print(TEST_PATH)(3)创建opera_excel_1.py来操作基本的excel
import xlrd from utils.path_config import FILE_PATH class OperationExcel: def __init__(self,sheet_num): self.sheet_num = sheet_num # 获取table数据 def get_data(self): data = xlrd.open_workbook(FILE_PATH) tables = data.sheets()[self.sheet_num] return tables # 获取单元格的行数 def get_lines(self): tables = self.get_data() return tables.nrows # 获取某一个单元格的内容 def get_cell_value(self,row,col): return self.get_data().cell_value(row,col) #获取第一行的列数 def cols_count(self): title = self.get_data().row_values(0) return len(title) """ if __name__ == '__main__': s = OperationExcel(0) s.cols_count() """(1)创建get_Columns_2.py来获取excel中的列号
#封装获取列号方法,以后维护方便一些(目的:获取id,url,请求方法,是否运行,预算结果等所在excel中的列号) class global_var: id = 0 case_name = 1 URL = 2 request_way = 3 header = 4 json_data = 5 exspect = 6 #获取id所在列号 def id_colnum(): return global_var.id #获取case_name所在列号 def case_name_colnum(): return global_var.case_name #获取URL所在列号 def URL_colnum(): return global_var.URL #获取request_way所在列号 def request_way_colnum(): return global_var.request_way #获取header所在列号 def header_colnum(): return global_var.header #获取json_data所在列号 def json_data_colnum(): return global_var.json_data #获取respect所在列号 def exspect_colnum(): return global_var.exspect(2)创建get_data_3.py来获取excel中的每一行
#获取EXCEl中数据 from utils.opera_excel_1 import OperationExcel from data import get_Columns_2 class GetData: def __init__(self,sheet_num): self.opera_excel = OperationExcel(sheet_num) # 获取EXCEL中所有数据 def data(self): arr_data1 = [] rows_count = self.opera_excel.get_lines() #行数循环 for i in range(1,rows_count): #列数循环 arr_data0 = [] for j in range(0,self.opera_excel.cols_count()): row_col_data = self.opera_excel.get_cell_value(i,j) arr_data0.append(row_col_data) arr_data1.append(arr_data0) # print(arr_data1[6]) return arr_data1 if __name__ == '__main__': s = GetData(0) s.data()(3)创建analyze_data_4.py来解析数据
#对数据进行解析处理组合得到有效数据,并执行熨平 from data import get_Columns_2,get_data_3 import json class Analyze: #对获取到的数据进行解析处理,并执行用例。 def analyze_data(self): raw_data = get_data_3.GetData(0).data() arr_list = [] for i in range(0,len(raw_data)): request_url = raw_data[i][get_Columns_2.URL_colnum()] request_way = raw_data[i][get_Columns_2.request_way_colnum()] request_header = raw_data[i][get_Columns_2.header_colnum()] request_data = raw_data[i][get_Columns_2.json_data_colnum()] #去除字符串中的换行符\n和多余的空格 request_data = request_data.replace('\n','').replace(' ','') request_expect = raw_data[i][get_Columns_2.exspect_colnum()] arr_list.append([request_url,request_way,request_header,request_data,request_expect]) # print(arr_list[2]) # print(type(arr_list)) return arr_list if __name__ == '__main__': s = Analyze() s.analyze_data()(1)在test下创建test_case.py文件
#coding=utf8 import unittest from utils.http_method import Method from data.analyze_data_4 import Analyze import json from ddt import ddt,data,unpack @ddt class TestMethod(unittest.TestCase): get_data = Analyze() data_all = get_data.analyze_data() def setUp(self): self.run = Method() @data(data_all[0]) @unpack def test_01_register(self,*args): #args[3]中含有中文,将字符串转为二进制 res = self.run.send_request(args[0],args[1],args[2],args[3].encode('utf-8')) # print(res) self.assertDictContainsSubset(json.loads(args[4]),res,msg="测试用例失败") @data(data_all[1]) @unpack def test_02_login(self,*args): res = self.run.send_request(args[0],args[1],args[2],args[3]) # print(res) global UserID UserID = res['ResultObj']['UserID'] self.assertDictContainsSubset(json.loads(args[4]),res['ResultObj'],msg="测试用例失败") return res @data(data_all[2]) @unpack def test_03_up_apikey(self,*args): res_dict3 = json.loads(args[3]) res_dict3['OperUserID'] = res_dict3['UserID'] = UserID res= self.run.send_request(args[0],args[1],args[2],res_dict3) # print(res) self.assertDictContainsSubset(json.loads(args[4]),res,msg="测试用例失败") @data(data_all[3]) @unpack def test_04_login_again(self,*args): res = self.run.send_request(args[0],args[1],args[2],args[3]) # print(res) global Token Token = res['ResultObj']['AccessToken'] self.assertDictContainsSubset(json.loads(args[4]),res['ResultObj'],msg="测试用例失败") @data(data_all[4]) @unpack def test_05_new_project(self,*args): global res_dict2 res_dict2 = json.loads(args[2]) res_dict2['AccessToken'] = Token res = self.run.send_request(args[0],args[1],res_dict2,args[3]) # print(res) global ProjectID ProjectID = res['ResultObj'] self.assertDictContainsSubset(json.loads(args[4]),res,msg="测试用例失败") @data(data_all[5]) @unpack def test_06_new_device(self,*args): res_dict3 = json.loads(args[3]) res_dict3['ProjectIdOrTag'] = str(ProjectID) res = self.run.send_request(args[0],args[1],res_dict2,res_dict3) # print(res) global deviceId1 deviceId1 = res['ResultObj'] self.assertDictContainsSubset(json.loads(args[4]),res,msg="测试用例失败") @data(data_all[6]) @unpack def test_07_new_sensor(self,*args): str0 = args[0].replace("{deviceId}",str(deviceId1)) res = self.run.send_request(str0,args[1],res_dict2,args[3]) # print(res) self.assertDictContainsSubset(json.loads(args[4]),res,msg="测试用例失败") @data(data_all[7]) @unpack def test_08_new_actor(self,*args): str0 = args[0].replace("{deviceId}",str(deviceId1)) res = self.run.send_request(str0,args[1],res_dict2,args[3]) # print(res) self.assertDictContainsSubset(json.loads(args[4]),res,msg="测试用例失败") @data(data_all[8]) @unpack def test_09_delete_project(self,*args): str3 = args[3].replace("{ProjectId}",str(ProjectID)) res = self.run.send_request(args[0],args[1],res_dict2,str3) # print(res) self.assertDictContainsSubset(json.loads(args[4]),res,msg="测试用例失败") if __name__ == "__main__": unittest.main(verbosity=2)我们把excel中的第一条注册用例预期结果中的"Status": 1改为"Status": 0,然后再运行一下,可以看到第一条用例是执行Fail的
地址:https://github.com/songteng2012/Interface
(1)模块划分不太合理。因为case之间关联性比较强,要把test_case.py中的流程拆分出来分到别的包里写。–>待优化