Python接口自動化之request請求封裝

作者:Gakki

1. 背景

我們在做自動化測試的時(shí)候,大家都是希望自己寫的代碼越簡潔越好,代碼重復(fù)量越少越好。那么,我們可以考慮將request的請求類型(如:Get、Post、Delect請求)都封裝起來。這樣,我們在編寫用例的時(shí)候就可以直接進(jìn)行請求了。

2. 源碼分析

我們先來看一下Get、Post、Delect等請求的源碼,看一下它們都有什么特點(diǎn)。

(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)分析結(jié)果

我們發(fā)現(xiàn),不管是Get請求、還是Post請求或者是Delect請求,它們到最后返回的都是request函數(shù)。那么,我們再去看一看request函數(shù)的源碼。

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源碼可以看出,它先創(chuàng)建一個(gè)Request,然后將傳過來的所有參數(shù)放在里面,再接著調(diào)用self.send(),并將Request傳過去。這里我們將不在分析后面的send等方法的源碼了,有興趣的同學(xué)可以自行了解。

分析完源碼之后發(fā)現(xiàn),我們可以不需要單獨(dú)在一個(gè)類中去定義Get、Post等其他方法,然后在單獨(dú)調(diào)用request。其實(shí),我們直接調(diào)用request即可。

3. requests請求封裝

代碼示例:

import requests

class RequestMain:
    def __init__(self):
        """

        session管理器
        requests.session(): 維持會話,跨請求的時(shí)候保存參數(shù)
        """
        # 實(shí)例化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,作為參數(shù)增加到url中         
        :param data: data類型傳參,字典、字節(jié)序列或文件對象,作為Request的內(nèi)容
        :param json: json傳參,作為Request的內(nèi)容
        :param headers: 請求頭,字典
        :param kwargs: 若還有其他的參數(shù),使用可變參數(shù)字典形式進(jìn)行傳遞
        :return:
        """

        # 對異常進(jìn)行捕獲
        try:
            """
            
            封裝request請求,將請求方法、請求地址,請求參數(shù)、請求頭等信息入?yún)ⅰ?            注 :verify: True/False,默認(rèn)為True,認(rèn)證SSL證書開關(guān);cert: 本地SSL證書。如果不需要ssl認(rèn)證,可將這兩個(gè)入?yún)⑷サ?            """
            re_data = self.session.request(method, url, params=params, data=data, json=json, headers=headers, cert=(client_crt, client_key), verify=False, **kwargs)
        # 異常處理 報(bào)錯(cuò)顯示具體信息
        except Exception as e:
            # 打印異常
            print("請求失敗:{0}".format(e))
        # 返回響應(yīng)結(jié)果
        return re_data


if __name__ == '__main__':
    # 請求地址
    url = '請求地址'
    # 請求參數(shù)
    payload = {"請求參數(shù)"}
    # 請求頭
    header = {"headers"}
    # 實(shí)例化 RequestMain()
    re = RequestMain()
    # 調(diào)用request_main,并將參數(shù)傳過去
    request_data = re.request_main("請求方式", url, json=payload, headers=header)
    # 打印響應(yīng)結(jié)果
    print(request_data.text)  

:如果你調(diào)的接口不需要SSL認(rèn)證,可將certverify兩個(gè)參數(shù)去掉。

4. 總結(jié)

本文只是簡單的介紹了Python接口自動化之request請求封裝,后期還有許多優(yōu)化的地方,希望和大家一起來探討。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容