一、文件夹组织
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 )
View Code
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
View Code
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
View Code
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
View Code
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
View Code
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)
后期加入:日志模块、结果验证、测试报告的生成、测试报告的自动邮件发送