Python接口框架--初版
一、文件夹组织
Python包文件夹
1.commonutils : 包含base64util、excelutil、md5util、timeutil、zipdirutil等公共方法
2.databaseutils : 包含databaseutil,操作数据库的公共方法
3.getdatautils : 包含从不同文件读取数据的方法
4.interfacecommonutils :
含filebase64ormd5:根据传递的所需返回类型值,获取文件的base64值或md5值
含interfaceobject:定义接口对象的类,类似Javabean
含interfaceconfigureinfo:获取配置文件信息,组装成接口对象
含interfacetestdata:获取处理后的请求参数
含interfacesign:获取请求签值的方法
含interfacerequest:请求接口的公共类
含executetestcase:执行用例的公共类
5.interfacetestscript : 执行接口用例的脚本
普通文件夹:
interfaceconfig文件夹:放接口相关配置信息的文件
interfacetestdata文件夹:放接口配置参数值的文件
interfaceexecuteconfig文件夹:放配置执行信息的文件
二、设计思路
1)通用方法提取出来作为公共方法
2)接口信息封装成一个对象:包含请求地址、请求头、请求方法、请求参数、请求参数中的特殊参数、用来验签的参数、签名参数名称、盐值
1 class InterfaceObject: 2 3 def __init__(self): 4 self.__url = '' 5 self.__headers = {} 6 self.__method = '' 7 self.__parameters = [] 8 self.__special_parameters = [] 9 self.__parameters_for_md5 = [] 10 self.__sign_name = '' 11 self.__salt_value = '' 12 13 # get方法 14 def get_url(self): 15 return self.__url 16 17 def get_headers(self): 18 return self.__headers 19 20 def get_method(self): 21 return self.__method 22 23 def get_parameters(self): 24 return self.__parameters 25 26 def get_special_parameters(self): 27 return self.__special_parameters 28 29 def get_parameters_for_md5(self): 30 return self.__parameters_for_md5 31 32 def get_sign_name(self): 33 return self.__sign_name 34 35 def get_salt_value(self): 36 return self.__salt_value 37 38 # set方法 39 def set_url(self, url): 40 self.__url = url 41 42 def set_headers(self, headers_dict): 43 self.__headers = headers_dict 44 45 def set_method(self, method): 46 self.__method = method 47 48 def set_parameters(self, parameters_list): 49 self.__parameters = parameters_list 50 51 def set_special_parameters(self, special_parameters_tuple_list): 52 self.__special_parameters = special_parameters_tuple_list 53 54 def set_parameters_for_md5(self, parameters_for_md5_list): 55 self.__parameters_for_md5 = parameters_for_md5_list 56 57 def set_sign_name(self, sign_name): 58 self.__sign_name = sign_name 59 60 def set_salt_value(self, salt_value): 61 self.__salt_value = salt_value 62 63 def __str__(self): 64 return ( 65 'url:' + self.__url + '\n' 66 'headers:' + str(self.__headers) + '\n' 67 'method:' + self.__method + '\n' 68 'parameters:' + str(self.__parameters) + '\n' 69 'special_parameters:' + str(self.__special_parameters) + '\n' 70 'parameters_for_md5:' + str(self.__parameters_for_md5) + '\n' 71 'sign_name:' + self.__sign_name + '\n' 72 'salt_value:' + self.__salt_value 73 )
3)请求参数中的特殊参数进行特殊处理(example:图片、文件)
1 class InterfaceConfigInfo: 2 # 获取配置文件配置的值 3 def __init__(self, file_path, interfaceName): 4 self.__config = configparser.ConfigParser() 5 self.__config.read(file_path) 6 self.__section = interfaceName + "InterfaceInfo" 7 self.__interface_url = self.__config.get(self.__section, 'interface_url') 8 self.__interface_headers = eval(self.__config.get(self.__section, 'interface_headers')) 9 self.__interface_method = self.__config.get(self.__section, 'interface_method') 10 self.__interface_parameters_str = self.__config.get(self.__section, 'interface_parameters') 11 self.__interface_special_parameters_str = self.__config.get(self.__section, 'interface_special_parameters') 12 self.__interface_sign_name = self.__config.get(self.__section, 'interface_sign_name') 13 self.__interface_parameters_for_md5_str = self.__config.get(self.__section, 'interface_parameters_for_md5') 14 self.__interface_salt_value = self.__config.get(self.__section,'interface_salt_value') 15 16 # 获取参数list 17 def __get_parameters_list(self): 18 interface_parameters_list = self.__interface_parameters_str.split(',') 19 return interface_parameters_list 20 21 # 获取需要特殊处理的参数list list中为元组类型(参数名,参数传递时的值处理,参数验签时的值处理) 22 # def __get_special_parameters_tuple_list(self): 23 # special_parameters_tuple_list = [] 24 # special_parameters_list = self.__interface_special_parameters_str.split('|') 25 # for parameter in special_parameters_list: 26 # special_parameters_tuple_list.append(tuple(eval(parameter))) 27 # return special_parameters_tuple_list 28 29 # 获取需要特殊处理的参数list list中为元组类型(参数名,参数传递时的值处理,参数验签时的值处理) 30 def __get_special_parameters_tuple(self): 31 if self.__interface_special_parameters_str: 32 special_parameters_tuple = tuple(eval(self.__interface_special_parameters_str)) 33 else: 34 special_parameters_tuple = None 35 return special_parameters_tuple 36 37 # 如果需要md5,获取加入md5的参数list 38 def __get_parameters_for_md5_list(self): 39 parameters_for_md5_list = self.__interface_parameters_for_md5_str.split(',') 40 return parameters_for_md5_list 41 42 # 获取InterfaceObject 43 def get_interface_object(self): 44 interface_object = InterfaceObject.InterfaceObject() 45 interface_object.set_url(self.__interface_url) 46 interface_object.set_headers(self.__interface_headers) 47 interface_object.set_method(self.__interface_method) 48 interface_object.set_parameters(self.__get_parameters_list()) 49 interface_object.set_special_parameters(self.__get_special_parameters_tuple()) 50 interface_object.set_parameters_for_md5(self.__get_parameters_for_md5_list()) 51 interface_object.set_sign_name(self.__interface_sign_name) 52 interface_object.set_salt_value(self.__interface_salt_value) 53 return interface_object
1 class InterfaceTestData: 2 # 参数:接口实例、测试数据文件 3 def __init__(self, interface_object, file_path): 4 if isinstance(interface_object, InterfaceObject.InterfaceObject): 5 self.__file_path = file_path 6 # 获取原始的测试数据 7 self.__parameters_list = interface_object.get_parameters() 8 self.__get_original_data = getdatafromtxtqf.GetDataFromTxtFile(self.__file_path, self.__parameters_list) 9 self.__original_test_data_list = self.__get_original_data.get_data_from_txt() 10 self.__interface_special_parameters_tuple = interface_object.get_special_parameters() 11 self.__sign_name = interface_object.get_sign_name() 12 self.__parameters_for_md5_list = interface_object.get_parameters_for_md5() 13 self.__salt_value = interface_object.get_salt_value() 14 else: 15 print('测试数据初始化失败!') 16 17 # 参数的值进行特殊处理 18 def operate_special_parameter_value(self): 19 if self.__original_test_data_list: 20 # 特殊参数特殊处理 21 if self.__interface_special_parameters_tuple: 22 count_of_special_parameter = int(len(self.__interface_special_parameters_tuple) / 3) 23 p_name_list = list(self.__interface_special_parameters_tuple[0:count_of_special_parameter]) 24 p_transport_operate = list(self.__interface_special_parameters_tuple[count_of_special_parameter:count_of_special_parameter * 2]) 25 p_md5_operate = list(self.__interface_special_parameters_tuple[count_of_special_parameter * 2:count_of_special_parameter * 3]) 26 for one_original_test_data in self.__original_test_data_list: 27 for p in zip(p_name_list, p_transport_operate, p_md5_operate): 28 p_list = list(p) 29 p_name = p_list[0] 30 p_t_need_operate_name = p_list[1] 31 p_md5_need_operate_name = p_list[2] 32 # 读文件获取的值 33 original_value = one_original_test_data[p_name] 34 if original_value: 35 # 传递时的值 36 p_t_value = FileBase64OrMd5.get_base64value_or_md5value(original_value, p_t_need_operate_name) 37 # 加签时的值 38 p_md5_value = FileBase64OrMd5.get_base64value_or_md5value(original_value, p_md5_need_operate_name) 39 if self.__sign_name: 40 one_original_test_data[p_name] = p_md5_value 41 sign = interfacesign.get_sign_from_parameters_dict(one_original_test_data, self.__salt_value) 42 one_original_test_data[self.__sign_name] = sign 43 one_original_test_data[p_name] = p_t_value 44 else: 45 one_original_test_data[p_name] = p_t_value 46 return self.__original_test_data_list
4)请求接口方法封装成一个公共类方法
1 class InterfaceRequest: 2 # 接口配置信息,命名规范:接口名_url , 接口名_headers 3 def __init__(self, interface_object): 4 if isinstance(interface_object, InterfaceObject.InterfaceObject): 5 self.__url = interface_object.get_url() 6 self.__headers = interface_object.get_headers() 7 self.__method = interface_object.get_method() 8 else: 9 print('InterfaceRequest-------初始化失败') 10 11 # 封装http get请求 12 def method_of_get(self, parameters_dict): 13 if self.__url: 14 if self.__headers: 15 result = requests.get(self.__url, params=parameters_dict, headers=self.__headers) 16 return result 17 else: 18 result = requests.get(self.__url, params=parameters_dict) 19 return result 20 else: 21 print('url error') 22 23 # 封装HTTP post请求 24 def method_of_post(self, parameters_dict): 25 if self.__url: 26 if self.__headers: 27 result = requests.post(self.__url, data=parameters_dict, headers=self.__headers) 28 return result 29 else: 30 result = requests.post(self.__url, data=parameters_dict) 31 return result 32 else: 33 print('url error') 34 35 # 封装HTTP post请求 Multipart-Encoded 36 def method_multipart_post(self, parameters_dict, files_dict): 37 if self.__url: 38 if self.__headers: 39 result = requests.post(self.__url, data=parameters_dict, files=files_dict, headers=self.__headers) 40 return result 41 else: 42 result = requests.post(self.__url, data=parameters_dict, files=files_dict) 43 return result 44 else: 45 print('url error') 46 47 # 封装HTTP put请求 48 def method_of_put(self, parameters_dict): 49 if self.__url: 50 if self.__headers: 51 result = requests.put(self.__url, data=parameters_dict, headers=self.__headers) 52 return result 53 else: 54 result = requests.put(self.__url, data=parameters_dict) 55 return result 56 else: 57 print('url error') 58 59 # 通用方法 60 def request_interface(self, parameters_dict): 61 if self.__method.upper() == 'GET': 62 result = self.method_of_get(parameters_dict) 63 elif self.__method.upper() == 'POST': 64 result = self.method_of_post(parameters_dict) 65 elif self.__method.upper() == 'PUT': 66 result = self.method_of_put(parameters_dict) 67 elif self.__method.upper() == 'MPOST': 68 result = self.method_multipart_post(parameters_dict) 69 else: 70 result = 'method配置错误' 71 return result
5)执行用例封装成一个公共类
1 class ExecuteTestCase: 2 3 def __init__(self, execute_file, interfaceName): 4 self.__config = configparser.ConfigParser() 5 self.__config.read(execute_file) 6 self.__section = interfaceName + "ExecuteInterfaceInfo" 7 self.__interface_name = interfaceName 8 self.__interface_config_file = self.__config.get(self.__section, 'interface_config_file') 9 self.__interface_test_data_file = self.__config.get(self.__section, 'interface_test_data_file') 10 11 def execute(self): 12 interface_configInfo_class = InterfaceConfigureInfo.InterfaceConfigInfo(self.__interface_config_file,self.__interface_name) 13 self.__interface_object = interface_configInfo_class.get_interface_object() 14 interface_test_data_class = InterfaceTestData.InterfaceTestData(self.__interface_object, self.__interface_test_data_file) 15 test_data_list = interface_test_data_class.operate_special_parameter_value() 16 interface_request_class = InterfaceRequest.InterfaceRequest(self.__interface_object) 17 for one_test_data in test_data_list: 18 response = interface_request_class.request_interface(one_test_data) 19 response.encoding = 'utf-8' 20 yield response 21 return response
6)执行脚本调用执行用例公共类中的方法:
if __name__ == '__main__':
execute_file = 'F:\\myProject\\QFAutoFrame\\interfaceexecuteconfig\\interfaceNameExecuteConfig.ini'
interface_name = 'interfaceName'
executeTestCase = ExecuteTestCase.ExecuteTestCase(execute_file, interface_name)
response = executeTestCase.execute()
for one in response:
print(one.text)
后期加入:日志模块、结果验证、测试报告的生成、测试报告的自动邮件发送