用Python发送HTTP请求:
测试数据存储在数据库中,所以是从数据库接口测试用例表中获取指定数据,然后使用requests模块发送HTTP请求,并获取返回包数据。
准备工作:
数据库使用MySQL
初始化测试用例表及其数据。
新建数据库接口用例表,并初始化测试数据。
DROP TABLE IF EXISTS `case_interface`;
CREATE TABLE `case_interface` (
`id` int NOT NULL AUTO_INCREMENT,
`name_interface` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '接口名称',
`exe_level` int NULL DEFAULT NULL COMMENT '执行优先级,0代表BVT',
`exe_mode` varchar(4) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '执行方式:POST、GET,默认是POST方式',
`url_interface` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '接口地址:直接使用 HTTP开头的详细地址',
`header_interface` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '接口请求的头文件,有则使用,无则不用',
`params_interface` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '接口请求的参数',
`result_interface` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '接口返回结果',
`code_to_compare` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '待比较的Code值,用户自定义比较值,例如ReturnCode和Code等,默认ReturnCode',
`code_actual` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '接口实际code返回值',
`code_expect` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '接口预期code返回值',
`result_code_compare` int NULL DEFAULT NULL COMMENT 'code 比较结果,1-pass,0-fail,2-无待比较参数,3-比较出错,4-返回包不合法,9-系统异常',
`params_to_compare` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '接口比较参数集合,用于比较参数的完整性',
`params_actual` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '接口实际返回参数',
`result_params_compare` int NULL DEFAULT NULL COMMENT '参数完整性比较结果,1-pass,0-fail, 2-获取参数集错误, 9-系统异常',
`case_status` int NULL DEFAULT 0 COMMENT '用例状态, 1-有效,0-无效',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '接口用例表';
INSERT INTO `case_interface` VALUES (1, 'comments.163', 0, 'get', 'https://api.uomg.com/api/comments.163', '{\'Accept\': \'application/json, text/javascript\'}', 'format=text', NULL, 'code', NULL, NULL, NULL, '[\'code\', \'data\', \'msg\']', NULL, NULL, 1, '2022-07-09 12:27:18', '2022-07-14 10:59:27');
用python操作HTTP请求的代码:
该代码是一个封装的、用python发送HTTP请求的类。
# coding = utf-8
'''
封装HTTP请求操作
1. http_request是主方法,直接供外部调用
2. __http_get、__http_post是实际底层分类调用的方法
'''
import requests, os, logging
from common import opmysql
from public import config
class RequestInterface:
# 定义处理不同类型的请求参数,包含字典、字符串、空值
def __new_param(self, param):
try:
if isinstance(param, str) and param.startswith('{'):
new_param = eval(param)
elif param == None:
new_param = ''
else:
new_param = param
except Exception as error: # 记录日志到log.txt中
new_param = ''
logging.basicConfig(filename=config.src_path + '/log/log.txt', level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
logger.exception(error)
return new_param
# POST请求,参数在body中
def __http_post(self, interface_url, headerdata, interface_param):
'''
:param interface_url: 接口地址
:param headerdata: 请求头文件
:param interface_param: 接口请求参数
:return: 字典形式结果
'''
try:
if interface_url != '':
temp_interface_param = self.__new_param(interface_param)
response = requests.post(url=interface_url, headers=headerdata, data=temp_interface_param,
verify=False, timeout=10)
if response.status_code == 200:
durtime = (response.elapsed.microseconds) / 1000 # 发起请求和响应到达的时间,单位ms
result = {'code': '0000', 'message': '成功', 'data': response.text}
else:
result = {'code': '2004', 'message': '接口返回状态错误', 'data': []}
elif interface_url == '':
result = {'code': '2002', 'message': '接口地址参数为空', 'data': []}
else:
result = {'code': '2003', 'message': '接口地址错误', 'data':[]}
except Exception as error: # 记录日志到log.txt文件
result = {'code': '9999', 'message': '系统异常', 'data': []}
logging.basicConfig(filename=config.src_path + '/log/log.txt', level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
logger.exception(error)
return result
# GET请求,参数在接口地址后面
def __http_get(self, interface_url, headerdata, interface_param):
'''
:param interface_url: 接口地址
:param headerdata: 请求头文件
:param interface_param: 接口请求参数
:return: 字典形式结果
'''
try:
if interface_url != '':
temp_interface_param = self.__new_param(interface_param)
if interface_url.endswith('?'):
requrl = interface_url + temp_interface_param
else:
requrl = interface_url + '?' + temp_interface_param
response = requests.get(url=requrl, headers=headerdata, verify=False, timeout=10)
# print(response)
if response.status_code == 200:
durtime = (response.elapsed.microseconds) / 1000 # 发起请求和响应到达的时间,单位ms
result = {'code': '0000', 'message': '成功', 'data': response.text}
else:
result = {'code': '3004', 'message': '接口返回状态错误', 'data': []}
elif interface_url == '':
result = {'code': '3002', 'message': '接口地址参数为空', 'data': []}
else:
result = {'code': '3003', 'message': '接口地址错误', 'data': []}
except Exception as error: # 记录日志到log.txt文件
result = {'code': '9999', 'message': '系统异常', 'data': []}
logging.basicConfig(filename=config.src_path + '/log/log.txt', level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
logger.exception(error)
return result
# 统一处理HTTP请求
def http_request(self, interface_url, headerdata, interface_param, request_type):
'''
:param interface_url: 接口地址
:param headerdata: 请求头文件
:param interface_param: 接口请求参数
:param request_type: 请求类型
:return: 字典形式结果
'''
try:
if request_type == 'get' or request_type == 'GET':
result = self.__http_get(interface_url, headerdata, interface_param)
elif request_type == 'post' or request_type == 'POST':
result = self.__http_post(interface_url, headerdata, interface_param)
else:
result = {'code': '1000', 'message': '请求类型错误', 'data': request_type}
except Exception as error:
result = {'code': '9999', 'message': '系统异常', 'data': []}
logging.basicConfig(filename=config.src_path + '/log/log.txt', level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
logger.exception(error)
return result
if __name__ == "__main__":
# 实例化HTTP请求类
test_interface = RequestInterface()
# 实例化MySQL处理类
test_db = opmysql.OperationDbInterface()
sen_sql = 'select exe_mode, url_interface, header_interface, params_interface from case_interface where id=3'
params_interface = test_db.select_one(sen_sql)
if params_interface['code'] == '0000':
url_interface=params_interface['data']['url_interface']
temp = params_interface['data']['header_interface']
headerdata = eval(params_interface['data'] ['header_interface']) # 将unicode转换成字典
param_interface = params_interface['data'] ['params_interface']
type_interface = params_interface['data']['exe_mode']
if url_interface != '' and headerdata != '' and params_interface != '' and type_interface != '':
result = test_interface.http_request(interface_url=url_interface, headerdata=headerdata,
interface_param=param_interface, request_type=type_interface)
if result['code'] == '0000':
result_resp = result['data']
# 将结果更新到case_interface表中
test_db.op_sql("update case_interface set result_interface='%s' where id=3 " %result_resp)
print('处理HTTP请求成功,返回数据是:%s' %result_resp)
else:
print('处理http请求失败')
else:
print('测试用例数据中有空值')
else:
print('获取接口测试用例数据失败')
这里使用的接口是从UomgAPI获取的免费接口。