Pytest 记录日志输出到控制台和写入文件
目录
自定义日志记录器和内置的日志记录器
项目代码
项目目录树
自定义日志记录器
函数源代码
pytest中定义和覆盖日志记录信息
使用cli定义Logging
使用pytest.ini定义Logging
修改单个测试级别的日志
日志输出的重要性不言而喻,不仅可以观测执行过程,更重要的是在发生bug时可以快速的定位到问题所在, Pytest 是出色的测试框架,但它不会自动显示 print 语句或日志的输出,这在尝试调试失败的测试或了解流程时可能会成为问题。同时也是支持设置日志级别,记录日志的到指定的文件
自定义日志记录器和内置的日志记录器
日志记录器的重要性在于可以随时设置不同级别的日志,python内置的日志记录器分类了5类的日志级别。标识日志的严重级别:
- - 未设置 NOTSET(0):此级别捕获所有消息,无论其严重性如何。
- - 调试 Debug(10):此级别用于任何可以帮助识别潜在问题的内容,例如变量值或程序执行的步骤。
- - 信息 Infor(20):此级别用于确认事情是否按预期工作。
- - 警告 Warning (30):此级别表示发生了意外情况,或者在不久的将来可能会出现一些问题(例如“磁盘空间不足”)。但是,该软件仍按预期工作。
- - 错误 Error(40):此级别表示存在更严重的问题,导致软件无法执行某项功能。
- - 严重 Critical(50):此级别表示一个非常严重的错误,可能会阻止程序继续运行。
自定义记录器允许您更方便地定义和处理这些级别,从而进一步提高记录过程的精度和控制。
基于以上的目标,本文旨在学习在python中设置 pytest 日志记录的过程。因此我们将探讨如何在 Pytest 中输出日志、如何禁用日志以及如何在单个测试级别更改日志级别。
项目代码
项目目录树
temperature_convertor
├── requirements.txt
├── src
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-310.pyc
│ │ └── custom_logger.cpython-310.pyc
│ ├── custom_logger.py
│ └── temp_convertor.py
└── tests├── __init__.py└── test_temp_convertor.py
运行环境:
% which python3
/usr/local/bin/python3
macOS 14.0
自定义日志记录器
我们使用了一个自定义记录器,配置为在级别显示日志消息。DEBUG
,
通过创建自己的记录器,您可以控制记录器的行为,从而可以自定义它以满足您的特定要求。
src/custom_logger.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This module is ***
# @Time : 2024/6/9 10:25
# @Author :
# function :
# @File : custom_logger.py
import logging
from enum import Enumclass LogLevel(Enum):DEBUG = logging.DEBUGINFO = logging.INFOWARNING = logging.WARNINGERROR = logging.ERRORCRITICAL = logging.CRITICALdef console_logger(name:str, level:LogLevel) -> logging.Logger:logger = logging.getLogger(f"__{name}__")logger.setLevel(level.value)# Create a console handler and set its levelconsole_handler = logging.StreamHandler()console_handler.setLevel(level.value)# Set the formatter for the console handlerformatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s",datefmt="%m/%d/%Y %I:%M:%S%p",)console_handler.setFormatter(formatter)# Add the console handler to the loggerlogger.addHandler(console_handler)return logger
函数源代码
这里通过温度的转换的的两个程序来调用设置的日志记录器。
src/temp_convertor.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This module is ***
# @Time : 2024/6/9 10:25
# @Author :
# function :
# @File : temp_convertor.py
from src.custom_logger import console_logger, LogLevelc_logger = console_logger(name="temp_convertor", level=LogLevel.DEBUG)def fahrenheit_to_celsius(fahrenheit: float) -> float:"""将华式摄氏度转换成摄氏度:param fahrenheit: 华式摄氏度:return:摄氏度"""c_logger.debug(f"Coverting {fahrenheit}°F to Celsius.")celsius = round((fahrenheit - 32) * 5 / 9, 2)c_logger.info(f"Result: {celsius}°C")return celsiusdef celsius_to_fahrenheit(celsius:float) -> float:"""将摄氏度转换成华式摄氏度:param celsius::return:"""c_logger.debug(f"Coverting {celsius}°F to fahrenheit.")fahrenheit = round((celsius * 9 / 5) + 32, 2)c_logger.info(f"Result: {fahrenheit}°C")return fahrenheitif __name__ == '__main__':print(fahrenheit_to_celsius(100))print(celsius_to_fahrenheit(100))
执行上述代码,检查代码基本逻辑正确
源代码没问题之后,编写一些单元测试来验证实用程序的功能。temp_convertor
tests/test_temp_convertor.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This module is ***
# @Time : 2024/6/9 10:26
# @Author :
# function :
# @File : test_temp_convertor.pyfrom src.temp_convertor import fahrenheit_to_celsius, celsius_to_fahrenheitdef test_fahrenheit_to_celsius():assert fahrenheit_to_celsius(90) == 32.22def test_celsius_to_fahrenheit():assert celsius_to_fahrenheit(19) == 66.2
pytest -s -v
学以致用,之前的其他的文章介绍了pytest 插件,pytest-sugagr.
❓❓❓ 如果您想覆盖源代码中设置的记录器仅用于测试,怎么样?也许是不同的格式,不同的日志级别,甚至输出到文件?
pytest中定义和覆盖日志记录信息
Pytest 提供了多种方法来控制测试过程中的日志记录。其中一种方法是通过 CLI 定义和覆盖默认日志记录格式。
使用cli定义Logging
pytest允许通过命令行参数的方式自定义日志输出格式和时间格式,这种灵活性使您能够根据自己的具体需求调整日志显示方式。这里给出一个示例:
pytest -s -v --log-cli-level=INFO --log-format="%(asctime)s %(levelname)s %(message)s" --log-date-format=" %Y-%m-%d %H:%M"
在该命令中,log format设置日志消息本身的格式,而log date format则设置日志消息中时间戳的格式。
这里看到已经将日志格式和级别重写为 Info信息 几倍。
使用pytest.ini定义Logging
如果使用持久化的配置,可以在pytest.ini文件中设置日志参数。此文件允许您在默认情况下启用CLI日志记录,并指定默认日志级别。以下是pytest.ini配置的示例:
pytest.ini
[pytest]
log_cli = true
log_cli_level = DEBUG
log_cli_format = %(asctime)s %(levelname)s %(message)s
log_cli_date_format = %Y-%m-%d %H:%M:%S
在这里的配置中,设置了几个参数如下所示:
- log_cli:启用到控制台的日志记录。
- log_cli_level:将日志级别设置为DEBUG。
- log_cli_format:设置记录消息的格式。
- log_cli_date_format:设置日志消息中时间戳的格式。
有关配置日志记录pytest.ini,当然也可以使用pyproject.tmol,tox.ini,setup.config,但是在Pytest中pytest.ini优先于其他几个配置文件,即使为空也是如此。
运行此操作,我们从关卡中获取每个测试的实时日志。DEBUG
上面定义了将日志输出到控制台,还可以将其写入文件供以后查询或查看执行信息。需要将文件处理器添加到配置文件中的【日志记录器 】,在Pytest.ini中
[pytest]
log_file = logs/temp_convertor_tests_run.log
log_file_date_format = %Y-%m-%d %H:%M:%S
log_file_format = %(asctime)s - %(name)s %(levelname)s %(message)s
log_file_level = DEBUG
执行pytest命令
pytest -s -v
此时会在tests目录下生成一个log文件
logs/temp_convertor_tests_run.log
2024-06-10 19:49:12 - __temp_convertor__ DEBUG Coverting 90°F to Celsius.
2024-06-10 19:49:12 - __temp_convertor__ INFO Result: 32.22°C
2024-06-10 19:49:12 - __temp_convertor__ DEBUG Coverting 19°F to fahrenheit.
2024-06-10 19:49:12 - __temp_convertor__ INFO Result: 66.2°C
当然还有其他的诸如禁用日志的功能,但如果在测试中可能只有小概率会使用禁用日志的功能
pytest -s -v --show-capture=no
修改单个测试级别的日志
某些时候,可能希望更改特定测试的日志级别,可能是为了调试该测试或减少日志输出中的干扰。Pytest 的夹具允许您执行此操作。
caplog
该夹具可以用于控制测试中的日志并与之交互,使用caplog,实现临时修改日志级别、捕获日志信息进行断言,在测试用例中新增
def test_celsius_to_fahrenheit_caplog_ex(caplog):caplog.set_level(logging.DEBUG, logger="__temp_conertor__")assert celsius_to_fahrenheit(19) == 66.2print("printing caplong records...")for record in caplog.records:print(record.levelname, record.message)
再次执行
pytest -s -v
输出显示测试的日志级别设置为 INFO,并且可以使用 和 访问和打印日志消息。record.levelname
record.message
.
在其他的文章中给出了配置控制台和记录到日志文件时,可以使用logger.config
或pytest.ini
来实现。logger.config
是通过编程的方式设置日志记录器的配置,而pytest.ini
是通过配置文件来设置pytest
的全局选项,包括日志选项。
pytest.ini
方式相对更简单和方便,因为它可以在一个地方集中管理所有的pytest
配置,并且不需要在每个测试文件中重复设置日志配置。通过在pytest.ini
文件中添加相应的日志配置选项,可以轻松地控制日志的输出级别、格式和文件路径等。
然而,如果你需要更细粒度的日志控制,或者需要在不同的测试用例中使用不同的日志配置,那么使用logger.config
可能更合适。通过编程方式设置日志记录器,可以根据具体的需求动态地调整日志配置。
综上所述,如果你希望简单地配置日志并在整个项目中使用相同的日志设置,推荐使用pytest.ini
。如果你需要更灵活的日志控制或在不同的测试用例中有不同的日志需求,可以考虑使用logger.config
。最终的选择取决于你的具体需求和项目的特点。
# pytest.ini
[pytest]
log_cli = True
log_cli_level = INFO
log_cli_format = %(asctime)s (%(levelname)s) | %(filename)s:%(lineno)s | %(message)s
log_cli_date_format = %Y-%m-%d %H:%M:%S
log_file = pytest_log.txt
log_file_level = INFO
log_file_date_format = %Y-%m-%d %H:%M:%S
log_file_format = %(asctime)s ( %(levelname)s ) %(filename)s:%(lineno)s | %(message)s
在上述代码中,log_cli = True
表示在执行过程中启动实时监测日志,log_cli_level
指定了监测日志的等级显示,log_cli_format
定义了输出日志的显示格式,log_cli_date_format
指定了显示日志的时间格式。
log_file
指定了存放日志文件的路径,log_file_level
表示文件中显示的日志等级,log_file_date_format
表示文件中显示的日志时间格式,log_file_format
表示文件中显示的日志格式。
要使用上述配置,需要在测试用例文件中导入logging
库,并在需要记录日志的地方使用logging
模块的方法输出日志信息,例如:
def test_demo_ini():import logginglogging.info(f'这是测试用例的info')logging.warning(f'这是测试用例的warning')logging.error(f'这是测试用例的error')assert 1
控制台输出:
在temp_convertor_tests_run.log日志文件中
相关文章:
Pytest 记录日志输出到控制台和写入文件
目录 自定义日志记录器和内置的日志记录器 项目代码 项目目录树 自定义日志记录器 函数源代码 pytest中定义和覆盖日志记录信息 使用cli定义Logging 使用pytest.ini定义Logging 修改单个测试级别的日志 日志输出的重要性不言而喻,不仅可以观测执行过程&…...
LINUX网络FTP服务
一、FTP服务 FTP服务:file transfer protocol :文件传输协议。在网络上进行双向传输,也是一个应用程序。不同的操作系统有不同的FTP软件,但使用的协议是一样的。 FTP协议基于TCP协议,有两个端口,即20和21。 20端口&…...
10 C++11
10 C11 1、类型推导1.1 auto关键字1.2 auto类型推断本质 2、类型计算2.1 类型计算分类2.2 类型计算的四种规则2.3 返回值类型计算 3、列表初始化4、Lambda表达式4.1 前置知识4.2 Lambda表达式4.3 捕获表 5、右值引用5.1 概念5.2 左值引用和右值引用 6、移动语义 1、类型推导 1…...
java的封装
为什么要封装?在java的面向对象的思想中,封装是指将类的实现细节包装,隐藏起来的方法。封装可以防止本类的代码和数据被外部定义的代码随机访问。 如何进行封装? 在定义一个类时,将类中的属性私有化,即使…...
为什么选择海外服务器?
如何选择跨境电商服务器:详细指南 选择合适的服务器是跨境电商企业成功的基础。服务器的性能和稳定性直接影响着网站的访问速度、用户体验和安全性,进而影响着企业的销量和利润。那么,跨境电商企业该如何选择服务器呢? 1. 确定目…...
k8s+springcloud+nacos部署配置
1 k8s 部署nacos-2.1.2配置k8s-nacos-statefulSet.yaml文件 apiVersion: v1 kind: Service metadata:name: nacos-headlessnamespace: rz-dtlabels:app: nacosannotations:service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec:# 3个端口打开&…...
梯度提升决策树(GBDT)
GBDT(Gradient Boosting Decision Tree),全名叫梯度提升决策树,是一种迭代的决策树算法,又叫 MART(Multiple Additive Regression Tree),它通过构造一组弱的学习器(树&am…...
数据结构之B树的原理与业务场景
B树是一种自平衡的树形数据结构,它能够保持数据有序,并且可以高效地进行查找、顺序访问、插入和删除操作。B树的设计是为了优化磁盘I/O操作,因为它可以减少磁盘访问次数,这在数据库和文件系统中非常有用。 1. B树的原理 节点的出…...
【Android面试八股文】你能说一说线程池管理线程的原理吗?
面试官(Interviewer): 欢迎参加面试,今天我们会讨论一些关于 Java 线程池管理的问题。你能给我解释一下 ThreadPoolExecutor 是如何管理线程的吗? 候选人(Candidate): 当然可以,ThreadPoolExecutor 是 Java 中用于创建和管理线程池的核心类。它通过一组核心参数来控制线…...
springer 在线投稿编译踩坑
springer投稿,在线编译踩坑总结 注意: 有的期刊需要双栏,而预定义的模板中可能为单栏,需要增加iicol选项。 例如: \documentclass[sn-mathphys-num]{sn-jnl}% —>\documentclass[sn-mathphys-num, iicol]{sn-jnl}…...
固态硬盘的指标
固态硬盘的指标主要包括以下几个方面: 接口类型:这是固态硬盘与外部设备连接的方式,常见的接口类型有SATA、PCIe和NVMe等。不同的接口类型决定了固态硬盘的传输速度和性能。例如,PCIe接口的固态硬盘通常比SATA接口的固态硬盘具有…...
mysql 分组后每个取最新的一条记录
在MySQL中,若要从一个分组中获取每组的最新一条记录(通常基于时间戳或其他递增的列),可以使用子查询或者窗口函数(如果MySQL版本支持)。 以下是两种不同的实现方法: 方法1: 使用子查询和LIMIT…...
Java语法和基本结构介绍
Java语法和基本结构是Java编程的基础,它决定了Java代码的书写方式和程序的结构。以下是Java语法和基本结构的一些关键点: 1.标识符和关键字:Java中的标识符是用来标识变量、函数、类或其他用户自定义元素的名称。关键字是预留的标识符&#x…...
TDengine 3.3.0.0 引入图形化管理工具、复合主键等 13 项关键更新
在涛思数据研发团队的努力下,TDengine 3.3.0.0 版本终于和大家见面了。这一版本中,我们引入了多项革新功能和性能优化,力求在为用户提供极致体验的同时,不断推动技术的前沿。 此次更新不仅针对开源社区版本,进行了一系…...
C++基础之红黑树
二叉搜索树 二叉搜索树(Binary Search Tree,BST)是一种二叉树,具有以下性质: 左子树节点值小于根节点值:对于树中的每个节点 x,其左子树中所有节点的值都小于 x 的值。右子树节点值大于根节点值…...
ClickHouse数据库对比、适用场景与入门指南
本文全面对比了ClickHouse与其他数据库(如StarRocks、HBase、MySQL、Hive、Elasticsearch等)的性能、功能、适用场景,并提供了ClickHouse的教学入门指南,旨在帮助读者选择合适的数据库产品并快速掌握ClickHouse的使用。 文章目录 …...
举例说明 如何通过SparkUI和日志定位任务莫名失败?
有一个Task OOM: 通过概览信息,发现Stage 10的Task 36失败了4次导致Job失败。概览信息中显示最后一次失败的退出代码(exit code)是143,意味着发生了内存溢出(OOM,即Out of Memory)。…...
Vue前端通过Axios的post方式传输数据,后端为什么一直接收的值是null?
沃靠!这个细节太细了,搞了我两个多小时才找到这个bug。 一、 首先官方文档给我的post请求的例子是这样的: axios.post(/user, {firstName: Fred,lastName: Flintstone}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);})…...
外链建设如何进行?
理解dofollow和nofollow链接,所谓dofollow链接,就是可以传递权重到你的网站的链接,这种链接对你的网站排名非常有帮助,这种链接可以推动你的网站在搜索结果中的位置向上爬,但一个网站全是这种有用的链接,反…...
深入理解Java正则表达式及其应用
正则表达式是一种强大的文本匹配和处理工具,可以在字符串中查找、替换、提取符合特定模式的内容。Java作为一种广泛应用的编程语言,提供了丰富的正则表达式支持。本文将深入探讨Java正则表达式的基本概念、语法以及常见应用场景,帮助读者全面…...
Gstreamer学习3----灌数据给管线之appsrc
参考资料 Basic tutorial 8: Short-cutting the pipeline gstreamer向appsrc发送帧画面的代码_gst appsrc可变帧率-CSDN博客 在官网教程Basic tutorial 8: Short-cutting the pipeline 里面,讲了一个例子,push音频数据给管线,视频的例子更…...
【深度学习量化交易1】一个金融小白尝试量化交易的设想、畅享和遐想
关注我的朋友们可能知道,我经常在信号处理的领域出没,时不时会发一些信号处理、深度学习科普向的文章。 不过算法研究久了,总想做一些更有趣的事情。 比如用深度学习算法赚大钱。。毕竟有什么事情能比暴富更有意思呢。 一、神经网络与彩票…...
【0基础学爬虫】爬虫基础之自动化工具 DrissionPage 的使用
概述 前三期文章中已经介绍到了 Selenium 与 Playwright 、Pyppeteer 的使用方法,它们的功能都非常强大。而本期要讲的 DrissionPage 更为独特,强大,而且使用更为方便,目前检测少,强烈推荐!!&a…...
c++_0基础_讲解7 练习
这一讲我为大家准备了几道题目,大家试着独自做一下(可能来自不同网站) 整数大小比较 - 洛谷 题目描述 输入两个整数,比较它们的大小。若 x>yx>y ,输出 > ;若 xyxy ,输出 ÿ…...
docker一些常用命令以及镜像构建完后部署到K8s上
docker一些常用命令以及镜像构建完后部署到K8s上 1.创建文件夹2.删除文件3.复制现有文件内容到新建文件4.打开某个文件5.查看文件列表6.解压文件(tar格式)7.解压镜像8.查看镜像9.删除镜像10.查看容器11.删除容器12.停止运行容器13.构建镜像14.启动容器15…...
在typora中利用正则表达式,批量处理图片
一,png格式 在 Typora 中批量将 HTML 图片标签转换为简化的 Markdown 图片链接,且忽略 alt 和 style 属性,可以按照以下步骤操作: 打开 Typora 并加载你的文档。按下 Ctrl H(在 Windows/Linux 上)或 Cmd…...
构建LangChain应用程序的示例代码:33、如何在LangChain框架中使用HumanInputChatModel来模拟人工输入的聊天模型教程
除了HumanInputLLM,LangChain还提供了一个伪聊天模型类,可以用于测试、调试或教育目的。这允许您模拟对聊天模型的调用,并模拟如果人类接收到这些消息会如何响应。 在这篇笔记中,我们将介绍如何使用这个模型。 我们首先在代理中…...
虚拟机使用桥接模式网络配置
1、获取本机的网络详细信息 windowr 输入cmd 使用ipconfig -all 一样即可 在自己的虚拟机中设置网络 虚拟机中的ip ---------192.168.36.*,不要跟自己的本机ip冲突 网关-----------192.168.36.254 一样即可 dns -----------一样即可,我多写了几个&am…...
韩顺平0基础学java——第24天
p484-508 System类 常见方法 System.arrycopy(src,0,dest,1,2); 表示从scr的第0个位置拷贝2个,放到目标数组索引为1的地方。 BigInteger和BigDecimal类 保存大整数和高精度浮点数 BigInte…...
leecode N皇后
深度优先遍历,然后回溯 思考得到的技巧: 1.先思考怎么用学过的数据结构解题 2.回溯不只需要知道最后一步,还需要知道之前所走的每一步 3. 棋盘的生成,.join([]),可以变列表为字符串 看题解得到的技巧: 1.妙啊…...
网站建设包括什么/百度云网盘下载
大部分的数据分析师都或多或少掉入这样的陷阱:每天大部分的工作都花在查数上,干着干着变成了“查数菇”。看上去帮老板或其他同事查数据是数据分析师天经地义的任务,怎么会成为陷阱呢?我来给你分析分析:业务部门需求多…...
北京seo公司华网白帽/郑州seo技术外包
博客要不要坚持更新 ,更新些什么内容 昨天刚推了一篇博客,虽然只是转载,但是还是有一点点象征性的意义的。不过感觉就好像写了一篇说说,没有一点成就。 本来按照计划,我还想写写一些技术笔记。毕竟之前看过一些博客的…...
网站开发设计思想报告/站长工具精品
SELECT DISTINCT 语句用于返回唯一不同的值。 SQL SELECT DISTINCT 语句 在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。 DISTINCT 关键词用于返回唯一不同的值。 SQL SELECT DISTINCT 语法 …...
网站后台如何上传图片/中国新闻网最新消息
1.AndFix只能修复方法级别的bug使用流程:添加依赖→封装工具类→生成差异包(.patch文件)→loadpatch方法更新源码:初始化源码:PatchManager→init(比较版本号,删除旧版本)加载源码:addpatch→initPatchs()→addpatch()…...
网站建设做的好/建设一个网站的具体步骤
刚刚看到一篇关于使用 PreApplicationStartMethod 的文章,地址:http://www.dotnetcurry.com/ShowArticle.aspx?ID570&AspxAutoDetectCookieSupport1 在 Razor 中,如果在页面中要使用 DateTimeFormatInfo,就是一个问题。 Razo…...
做网站webform mvc/优化设计七年级上册数学答案
●MySQL事务隔离级别(1)●第1节:事务概述第2节:MySQL4种事务隔离级别分析第3节:总结1 事务概述什么是事务?数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。事务的使用是数据库管理系统区别文件系统的…...