关于python:Python接口自动化之request请求封装

本文首发于:行者AI

咱们在做自动化测试的时候,大家都是心愿本人写的代码越简洁越好,代码反复量越少越好。那么,咱们能够思考将request的申请类型(如:Get、Post、Delect申请)都封装起来。这样,咱们在编写用例的时候就能够间接进行申请了。

1. 源码剖析

咱们先来看一下Get、Post、Delect等申请的源码,看一下它们都有什么特点。

(1)Get申请源码


    def get(self, url, **kwargs):
        r"""Sends a GET request. Returns :class:`Response` object.
        :param url: URL for the new :class:`Request` object.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
         """
        
        kwargs.setdefault('allow_redirects', True)
        return self.request('GET', url, **kwargs) 

(2)Post申请源码


    def post(self, url, data=None, json=None, **kwargs):
        r"""Sends a POST request. Returns :class:`Response` object.
        :param url: URL for the new :class:`Request` object.
        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
        object to send in the body of the :class:`Request`.
        :param json: (optional) json to send in the body of the :class:`Request`.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        """
    
        return self.request('POST', url, data=data, json=json, **kwargs)  

(3)Delect申请源码


    def delete(self, url, **kwargs):
        r"""Sends a DELETE request. Returns :class:`Response` object.
        :param url: URL for the new :class:`Request` object.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        """
    
        return self.request('DELETE', url, **kwargs)

(4)剖析后果

咱们发现,不论是Get申请、还是Post申请或者是Delect申请,它们到最初返回的都是request函数。那么,咱们再去看一看request函数的源码。


    def request(self, method, url,
            params=None, data=None, headers=None, cookies=None, files=None,
            auth=None, timeout=None, allow_redirects=True, proxies=None,
            hooks=None, stream=None, verify=None, cert=None, json=None):
        """Constructs a :class:`Request <Request>`, prepares it and sends it.
        Returns :class:`Response <Response>` object.
    
        :param method: method for the new :class:`Request` object.
        :param url: URL for the new :class:`Request` object.
        :param params: (optional) Dictionary or bytes to be sent in the query
            string for the :class:`Request`.
        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
            object to send in the body of the :class:`Request`.
        :param json: (optional) json to send in the body of the
            :class:`Request`.
        :param headers: (optional) Dictionary of HTTP Headers to send with the
            :class:`Request`.
        :param cookies: (optional) Dict or CookieJar object to send with the
            :class:`Request`.
        :param files: (optional) Dictionary of ``'filename': file-like-objects``
            for multipart encoding upload.
        :param auth: (optional) Auth tuple or callable to enable
            Basic/Digest/Custom HTTP Auth.
        :param timeout: (optional) How long to wait for the server to send
            data before giving up, as a float, or a :ref:`(connect timeout,
            read timeout) <timeouts>` tuple.
        :type timeout: float or tuple
        :param allow_redirects: (optional) Set to True by default.
        :type allow_redirects: bool
        :param proxies: (optional) Dictionary mapping protocol or protocol and
            hostname to the URL of the proxy.
        :param stream: (optional) whether to immediately download the response
            content. Defaults to ``False``.
        :param verify: (optional) Either a boolean, in which case it controls whether we verify
            the server's TLS certificate, or a string, in which case it must be a path
            to a CA bundle to use. Defaults to ``True``.
        :param cert: (optional) if String, path to ssl client cert file (.pem).
            If Tuple, ('cert', 'key') pair.
        :rtype: requests.Response
        """
        # Create the Request.
        req = Request(
            method=method.upper(),
            url=url,
            headers=headers,
            files=files,
            data=data or {},
            json=json,
            params=params or {},
            auth=auth,
            cookies=cookies,
            hooks=hooks,
        )
        prep = self.prepare_request(req)
    
        proxies = proxies or {}
    
        settings = self.merge_environment_settings(
            prep.url, proxies, stream, verify, cert
        )
    
        # Send the request.
        send_kwargs = {
            'timeout': timeout,
            'allow_redirects': allow_redirects,
        }
        send_kwargs.update(settings)
        resp = self.send(prep, **send_kwargs)
    
        return resp    

从request源码能够看出,它先创立一个Request,而后将传过来的所有参数放在外面,再接着调用self.send(),并将Request传过来。这里咱们将不在剖析前面的send等办法的源码了,有趣味的同学能够自行理解。

剖析完源码之后发现,咱们能够不须要独自在一个类中去定义Get、Post等其余办法,而后在独自调用request。其实,咱们间接调用request即可。

2. requests申请封装

代码示例:


    import requests
    
    class RequestMain:
        def __init__(self):
            """
    
            session管理器
            requests.session(): 维持会话,跨申请的时候保留参数
            """
            # 实例化session
            self.session = requests.session()
    
        def request_main(self, method, url, params=None, data=None, json=None, headers=None, **kwargs):
            """
    
            :param method: 申请形式
            :param url: 申请地址
            :param params: 字典或bytes,作为参数减少到url中         
            :param data: data类型传参,字典、字节序列或文件对象,作为Request的内容
            :param json: json传参,作为Request的内容
            :param headers: 申请头,字典
            :param kwargs: 若还有其余的参数,应用可变参数字典模式进行传递
            :return:
            """
    
            # 对异样进行捕捉
            try:
                """
                
                封装request申请,将申请办法、申请地址,申请参数、申请头等信息入参。
                注 :verify: True/False,默认为True,认证SSL证书开关;cert: 本地SSL证书。如果不须要ssl认证,可将这两个入参去掉
                """
                re_data = self.session.request(method, url, params=params, data=data, json=json, headers=headers, cert=(client_crt, client_key), verify=False, **kwargs)
            # 异样解决 报错显示具体信息
            except Exception as e:
                # 打印异样
                print("申请失败:{0}".format(e))
            # 返回响应后果
            return re_data


    if __name__ == '__main__':
        # 申请地址
        url = '申请地址'
        # 申请参数
        payload = {"申请参数"}
        # 申请头
        header = {"headers"}
        # 实例化 RequestMain()
        re = RequestMain()
        # 调用request_main,并将参数传过来
        request_data = re.request_main("申请形式", url, json=payload, headers=header)
        # 打印响应后果
        print(request_data.text)  

:如果你调的接口不须要SSL认证,可将certverify两个参数去掉。

3. 总结

本文只是简略的介绍了Python接口自动化之request申请封装,前期还有许多优化的中央,心愿和大家一起来探讨。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理