用Python发送HTTP请求

1.新建数据库接口用例表,并初始化测试数据

CREATE TABLE case_interface (
id int(2) NOT NULL AUTO_INCREMENT,
name_interface varchar(128) NOT NULL COMMENT '接口名称',
exe_level int(2) DEFAULT NULL COMMENT '执行优先级,0代表BVT',
exe_mode varchar(4) DEFAULT NULL COMMENT '执行方式:post,get,默认是post方式',
url_interface varchar(128) DEFAULT NULL COMMENT '接口地址:如果以http开头的则直接使用改地址,否则拼接上不同环境的ip前缀作为接口地址',
header_interface text COMMENT '接口请求的头文件,有则使用,无则调用配置文件',
params_interface varchar(256) DEFAULT NULL COMMENT '接口请求的参数',
result_interface text COMMENT '接口返回结果',
code_to_compare varchar(16) DEFAULT NULL COMMENT '待比较的code值,用户自定义比较值,例如returncode和code等,默认returncode',
code_actual varchar(16) DEFAULT NULL COMMENT '接口实际code实际返回值',
code_expect varchar(16) DEFAULT NULL COMMENT '接口预期code返回值',
result_code_compare int(2) DEFAULT NULL COMMENT 'code比较结果,1-pass,0-fail,2-无待比较参数,3-比较出错,4-返回包不合法,9-系统异常',
params_to_compare varchar(256) DEFAULT NULL COMMENT '接口比较参数集合,用于比较参数完整性',
params_actual text COMMENT '接口实际返回参数',
result_params_compare int(2) DEFAULT NULL COMMENT '参数完整性比较结果,1-pass,0-fail,2-获取参数集错误,9-系统异常',
case_status int(2) DEFAULT '0' COMMENT '用例状态 1-有效,0-无效',
create_time datetime DEFAULT NULL COMMENT '创建时间',
update_time timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='接口用例表'

INSERT INTO `case_interface` (`name_interface`, `exe_level`, `exe_mode`, `url_interface`, `header_interface`, `params_interface`, `code_to_compare`,  `code_expect`, `params_to_compare`, `case_status`, `create_time`, `update_time`) VALUES ('getIpInfo.php', 0, 'GET', 'http://ip.taobao.com/service/getIpInfo.php', '{\'Host\':\'ip.taobao.com\'}', 'ip=63.223.108.4', 'code', '0', '[\'code\',\'data\',\'country\']', 1, NOW(), NOW());

2.发送HTTP请求实例

2.1 Python发送HTTP请求的流程

请添加图片描述

2.2 用Python操作HTTP请求的代码

request.py整体结构

# coding:utf-8

"""
封装HTTP请求操作
http_request是主方法,直接供外部调用
__http_get __http_post是实际底层分类调用的方法
"""
import  requests,od,logging
from common import opmysql
from public import config

class RequestInterface():
    # 定义处理不同类型的请求参数,包含字典、字符串、空值
    def __new_param(self,param):

    # POST请求,参数在body中
    def __http_post(self,interface_url,headerdata,interface_param):

    # GET请求,参数在接口地址后
    def __http_get(self,interface_url,headerdata,interface_param):

    # 统一处理HTTP请求
    def http_request(self,interface_url,headerdata,interface_param,request_type):

    if __name__ == "__main__":
        # 实例化
        test_interface = RequestInterface()
        # 实例化mysql处理类
        test_db = opmysql.OperationDbInterface()

        sen_sql = "select exe_mode,url_interface,header_interface,params_interface from case_interface " \
                  "where name_interface = 'getIpInfo.php' and id=1"
        params_interface = test_db.select_one(sen_sql)
        # 返回{'code':'0000','message':'执行单条查询操作成功','data':results}
        # data存放查询到的数据 results是查询到的数据库记录

        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'])
            # eval() eval()函数用来执行一个字符串表达式,并返回表达式的值。还可以把字符串转化为list、tuple、dict
            param_interface = params_interface['data']['params_interface']
            type_interface = params_interface['data']['exe_mode']

            if url_interface !='' and headerdata != '' and param_interface !='' and type_interface != '':
                result = test_interface.http_request(interface_url=url_interface,headerdata=headerdata,
                                                     interface_param=params_interface,request_type=type_interface)

                if result['code'] == '0000':
                    # 请求成功的话将应答的data记录进数据库
                    result_resp=result['data']
                    test_db.op_sql("UPDATE case_interface SET result_interface='%s' where id=1" %result_resp)
                    print("处理HTTP请求成功,返回数据是: %s" %result_resp)
                else:
                    print("处理HTTP请求失败")
            else:
                print("测试用例数据中有空值")
        else:
            print("获取接口测试用力数据失败")

def __new_param(self,param):

# 定义处理不同类型的请求参数,包含字典、字符串、空值
    def __new_param(self,param):
        try:
            if isinstance(param,str) and param.startswith('{'):
                # 若参数是字符串类型字典 用eval()将其还原成字典形式
                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/syserror.log',level=logging.DEBUG,
                                encoding='utf-8',
                                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')

            logger = logging.getLogger(__name__)
            logger.exception(error)
        return new_param

def __http_post(self,interface_url,headerdata,interface_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)
                # verify=false 不验证ssl证书
                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:
            result = {'code':'9999','message':'系统异常','data':[]}
            logging.basicConfig(filename=config.src_path + '/log/syserror.log',level=logging.DEBUG,
                                encoding='utf-8',
                                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
            logger = logging.getLogger(__name__)
            logger.exception(error)
        return result

def __http_get(self,interface_url,headerdata,interface_param)

# 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=interface_url,headers=headerdata,verify=False,timeout=10)
                # print response

                if response.status_code == 200:
                    # durtime = (response.elapsed.microseconds) / 1000
                    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:
            result = {'code': '9999', 'message': '系统异常', 'data': []}
            logging.basicConfig(filename=config.src_path + '/log/syserror.log', level=logging.DEBUG,
                                encoding='utf-8',
                                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
            logger = logging.getLogger(__name__)
            logger.exception(error)
        return result

def http_request(self,interface_url,headerdata,interface_param,request_type):

# 统一处理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/syserror.log', level=logging.DEBUG,
                                encoding='utf-8',
                                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
            logger = logging.getLogger(__name__)
            logger.exception(error)
        return result

报错

请添加图片描述
日志如下:
请添加图片描述
字典类型不能直接和string类型+拼接
temp_interface_param 改为 str(temp_interface_param)
请添加图片描述
改完就好了
请添加图片描述
会提示不安全因为没有验证ssl证书

请添加图片描述
请添加图片描述
可以看到result_interface改变了。

9.4

重新用这个代码生成数据的时候报错了
请添加图片描述
TypeError:列表索引必须是整数或片,而不是str。
应该是145行的params_interface的索引出错了。
加了两行打印代码但是打印出来的只有一个[]。
请添加图片描述
应该是数据库也有问题导致没搜到记录。
请添加图片描述
sql语句是这样的

select exe_mode,url_interface,header_interface,params_interface from case_interface where name_interface = ‘getIpInfo.php’ and id=1"

没有id为1的记录所以搜索出错了(昨天试验的时候删了第一条)。改动数据库id为1刷新之后还是2,所以就改了代码为id=2,又产生了新的错误。

请添加图片描述
3004是接口返回状态错误。
请添加图片描述
又试了一次成功了。应该是测试网站不稳定上一次拒绝了访问(status_code != 200)
请添加图片描述
但是这次返回的信息提示:需要字符串参数

“msg”:“Required String parameter ‘ip’ is not present”,“code”:2

不知道哪里出错了所以加了个打印语句看response.status_code请添加图片描述
http返回包的状态码是404
改来改去又尝试了几次
请添加图片描述
应该是这个接口不稳定导致的,改一改测试数据试试看。
请添加图片描述
请添加图片描述
2004,又是接口返回状态错误。返回包的status_code是403。
没改变任何地方又执行一次报错有不一样。
请添加图片描述
日志记录了错误
请添加图片描述


版权声明:本文为a_Seal_with_code原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。