四、封装日志功能
要想记录请i去和返回的信息,只需要在之前创建的http_client.py
模块做修改就行。那么先封装一个日志工具。
在项目下创建包名为utils
和logs
目录,紧接着utils
包下创建logger.py
。
# utils/logger.py
import os
import time
import logging
import json as _json
root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# 建立一个filehandler来把日志记录在文件里,级别为debug以上
fh = logging.FileHandler("{}/logs/{}.log".format(root_path, time.strftime('%Y%m%d', time.localtime())))
fh.setLevel(logging.DEBUG)
# 建立一个streamhandler来把日志打在CMD窗口上,级别为error以上
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
# 设置日志格式
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# 将相应的handler添加在logger对象中
logger.addHandler(ch)
logger.addHandler(fh)
接着修改http_client.py
import json as _json
import requests
from utils.logger import api_logger
class HttpClient():
# 接口做post一般都是采用json格式进行提交
__headers = {
"content-type": "application/json;charset=UTF-8"
}
def __init__(self):
self.__session = requests.session()
def get(self, path, **kwargs):
return self.__request(path, 'GET', **kwargs)
def post(self, path, data=None, json=None, **kwargs):
return self.__request(path, 'POST', data, json, **kwargs)
def __request(self, url, method, data=None, json=None, **kwargs):
headers = kwargs.get("headers")
params = kwargs.get("params")
# 如果传入header不为空,那么更新header
if headers:
self.__headers.update(headers)
self.__request_log(url, method, data, json, params, self.__headers)
resp = None
if method == "GET":
resp = self.__session.get(url, **kwargs)
elif method == "POST":
resp = requests.post(url, data, json, **kwargs)
self.__response_log(resp)
return resp
def __request_log(self, url, method, data=None, json=None, params=None, headers=None):
api_logger.info("接口请求地址: {}".format(url))
api_logger.info("接口请求方式: {}".format(method))
api_logger.info("接口请求头: {}".format(_json.dumps(headers, indent=4, ensure_ascii=False)))
api_logger.info("接口请求 params 参数: {}".format(_json.dumps(params, indent=4, ensure_ascii=False)))
api_logger.info("接口请求体 data 参数 : {}".format(_json.dumps(data, indent=4, ensure_ascii=False)))
api_logger.info("接口请求体 json 参数: {}".format(_json.dumps(json, indent=4, ensure_ascii=False)))
def __response_log(self, resp):
try:
api_logger.info("返回信息 : {}".format(resp.text, ensure_ascii=False))
except Exception as e:
api_logger.error('系统错误:{}'.format(e))
我们再次执行测试,查看logs文件下的日志
至此,日志封装功能完成。
实际工作中的自动化场景复杂程度远远不止如此。
- 公共方法可能在多个场景被使用,那么就需要在抽离出一个业务层
- 接口入参也需要单独抽离,方便统一维护
- 用例层抽离,方便统一管理
下一章节会封装业务层,数据层,测试用例层。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?