Эта статья была впервые опубликована на:Уокер ИИ
Когда мы проводим автоматизированное тестирование, все надеются, что код, который они пишут, будет максимально лаконичным, и чем меньше повторений кода, тем лучше. Затем мы можем рассмотреть возможность инкапсуляции типов запроса (например, запросы Get, Post, Delect). Таким образом, мы можем делать запросы непосредственно при написании вариантов использования.
1. Анализ исходного кода
Давайте сначала посмотрим на исходный код Get, Post, Delect и других запросов и посмотрим, какие у них характеристики.
(1) Получить исходный код запроса
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) Исходный код пост-запроса
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) Удалить исходный код запроса
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, все они возвращают функцию запроса в конце. Затем давайте еще раз взглянем на исходный код функции запроса.
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
Как видно из исходного кода запроса, он сначала создает запрос, затем помещает в него все переданные параметры, затем вызывает self.send() и передает запрос. Здесь мы не будем анализировать исходный код следующих методов, таких как send, и заинтересованные студенты могут разобраться в этом сами.
Проанализировав исходный код, мы обнаружили, что нам не нужно определять Get, Post и другие методы в отдельном классе, а затем отдельно вызывать request. На самом деле, мы можем вызвать запрос напрямую.
2. запрашивает инкапсуляцию запроса
Пример кода:
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, вы можете установитьcertиverifyДва параметра удалены.
3. Резюме
Эта статья лишь кратко знакомит с инкапсуляцией запросов для автоматизации интерфейса Python.На более позднем этапе еще предстоит много оптимизаций, и я надеюсь обсудить их с вами.
PS: Для получения дополнительной технической галантереи, пожалуйста, обратите внимание на [Публичный аккаунт | xingzhe_ai] и обсудите с ходоками!