我們在做自動化測試的時候,大家都是希望自己寫的代碼越簡潔越好,代碼重復量越少越好。那么,我們可以考慮將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-likeobject 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 querystring for the :class:`Request`.:param data: (optional) Dictionary, list of tuples, bytes, or file-likeobject 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 enableBasic/Digest/Custom HTTP Auth.:param timeout: (optional) How long to wait for the server to senddata 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 andhostname to the URL of the proxy.:param stream: (optional) whether to immediately download the responsecontent. Defaults to ``False``.:param verify: (optional) Either a boolean, in which case it controls whether we verifythe server's TLS certificate, or a string, in which case it must be a pathto 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 requestsclass RequestMain:def __init__(self):"""session管理器requests.session(): 維持會話,跨請求的時候保存參數"""# 實例化sessionself.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_dataif __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認證,可將cert與verify兩個參數去掉。
最后感謝每一個認真閱讀我文章的人,禮尚往來總是要有的,雖然不是什么很值錢的東西,如果你用得到的話可以直接拿走:【文末領取】
???? 【下面是我整理的2023年最全的軟件測試工程師學習知識架構體系圖+全套資料】
一、Python編程入門到精通
二、接口自動化項目實戰
三、Web自動化項目實戰

四、App自動化項目實戰
五、一線大廠簡歷

六、測試開發DevOps體系
七、常用自動化測試工具

八、JMeter性能測試
九、總結(尾部小驚喜)
生命不息,奮斗不止。每一份努力都不會被辜負,只要堅持不懈,終究會有回報。珍惜時間,追求夢想。不忘初心,砥礪前行。你的未來,由你掌握!
生命短暫,時間寶貴,我們無法預知未來會發生什么,但我們可以掌握當下。珍惜每一天,努力奮斗,讓自己變得更加強大和優秀。堅定信念,執著追求,成功終將屬于你!
只有不斷地挑戰自己,才能不斷地超越自己。堅持追求夢想,勇敢前行,你就會發現奮斗的過程是如此美好而值得。相信自己,你一定可以做到!