0.背景
背景:成熟的项目体系或架构中,一定是多个项目或模块在线上同时运行
缘由:解决公司实际业务接口自动化测试中跨项目请求联调
1.封装
"""
@Author: yl
@File: new_request.py
@Time: 2023/02/13 20:05:14
"""
import ujson
import logging
import requests
import warnings
import threading
from setting import app_cof
from requests import Response
from typing import Any, Literal, TypeVar
T = TypeVar("T")
requests.packages.urllib3.disable_warnings()
warnings.filterwarnings('ignore')
def dictToUriStr(content: dict):
"""字典转为uri格式的字符串"""
if not content:
return ""
res: str = "?"
keys: list = list(content.keys())
for index, item in enumerate(content):
res += (item + "=")
res += str(content.get(item))
if index < len(keys) - 1:
res += "&"
return res
# noinspection DuplicatedCode
class RequestHandle:
"""requests请求封装"""
_instance: dict = {}
lock = threading.Lock()
def __new__(cls, *args, **kwargs):
if cls._instance :
return cls._instance
with cls.lock:
if not cls.__instance:
cls.__instance = super().__new__(cls)
return cls.__instance
def visited(self, method: str, url: str, **kwargs) -> Response:
return requests.request(method=method.upper(), url=url, **kwargs)
def currency(
self,
_module: str,
method: Literal["get", "post", "put", "patch", "delete"],
point: str,
content_type: str = "application/json;charset=UTF-8",
resful: bool = True,
**kwargs
) -> T | Response:
"""
Args:
_module(str): request module
method (str): request method
point (str): request url
content_type (str): request headers content type, default: json
resful (bool): whether to serialize output
"""
headers: dict = {
"Content-Type": content_type,
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip"
}
match _module:
case "first":
headers["access-token"] = self.db.get("FirstToken")
_url: str = app_cof.FirstUrl + point
case "second":
headers["access-token"] = self.db.get("SecondToken")
_url: str = app_cof.SecondUrl + point
case "third":
headers["access-token"] = self.db.get("ThirdToken")
_url: str = app_cof.ThirdUrl + point
case "fourth":
headers["access-token"] = self.db.get("FourthToken")
_url: str = app_cof.FourthUrl + point
case "fifth":
headers["access-token"] = self.db.get("FifthToken")
_url: str = app_cof.FifthUrl + point
case _:
raise Exception("request module to be implemented!")
params: dict = kwargs.get("params", {})
# output request method and uri information
logging.info("{}, {}".format(method, point + dictToUriStr(params)))
res: Response = self.visited(method, _url, headers=headers, **kwargs)
assert res.status_code in (200, 201, 204)
if resful:
return ujson.loads(str(res.content, encoding="utf-8"))
return res
def first_request_json(
self,
method: str,
point: str,
resful: bool = False,
**kwargs
) -> Any | Response:
"""First App Request, Type: json"""
return self.currency(
_module="first",
method=method,
point=point,
resful=resful,
**kwargs
)
def first_request_xml(
self,
method: str,
point: str,
content_type: str = "text/xml;charset=utf-8",
resful: bool = False,
**kwargs
) -> Any | Response:
"""First App Request, Type: xml"""
return self.currency(
_module="first",
method=method,
point=point,
content_type=content_type,
resful=resful,
**kwargs
)
def second_request_json(
self,
method: str,
point: str,
resful: bool = True,
**kwargs
) -> Any | Response:
"""Second App Request, Type: json"""
return self.currency(
_module="second",
method=method,
point=point,
resful=resful,
**kwargs
)
...
reh: RequestHandle = RequestHandle()
2.使用
"""
@Author: yl
@File: new_request.py
@Time: 2023/02/13 20:15:28
"""
import allure
from utils.new_request import reh
@allure.story("查询用户")
def getUserList(user_id: str, **kwargs) -> Any | Response:
"""
:param user_id: 用户id
"""
point: str = f"/api/user/list"
params: dict = {
"keyword": kwargs.get("keyword", ""),
"page": kwargs.get("page", 0),
"size": kwargs.get("size", 10),
"sort": kwargs.get("keyword", "id,desc")
}
content: Response = reh.first_request_json('get', point, params=params)
return content
@allure.story("新增用户")
def postUserAdd(mobile: str, pwd: str, role: str = "stu", **kwargs) -> Any | Response:
"""
:param mobile: 手机号
:param pwd: 密码
:param role: 角色, 默认: 学生
"""
point: str = f"/api/user/save"
params: dict = {
"role": role
}
payload: dict = {
"mobile": mobile,
"pwd": pwd
}
content: Response = reh.first_request_json('post', point, params=params, json=payload)
return content
- from setting import app_cof: 项目配置项
- self.db.get(“xxx”): 登陆后将token存储在db中获取
- 每个项目的请求,如first_request_json, second_request_json… 均可以实现定制化请求;