一、文件夹组织

  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)接口信息封装成一个对象:包含请求地址、请求头、请求方法、请求参数、请求参数中的特殊参数、用来验签的参数、签名参数名称、盐值

python接口测试框架源码 python 接口框架_请求参数

python接口测试框架源码 python 接口框架_请求参数_02

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:图片、文件)

python接口测试框架源码 python 接口框架_请求参数

python接口测试框架源码 python 接口框架_请求参数_02

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

python接口测试框架源码 python 接口框架_请求参数

python接口测试框架源码 python 接口框架_请求参数_02

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)请求接口方法封装成一个公共类方法

python接口测试框架源码 python 接口框架_请求参数

python接口测试框架源码 python 接口框架_请求参数_02

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)执行用例封装成一个公共类

python接口测试框架源码 python 接口框架_请求参数

python接口测试框架源码 python 接口框架_请求参数_02

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)

 

后期加入:日志模块、结果验证、测试报告的生成、测试报告的自动邮件发送