如何单元测试日志文件?为何pytest -s无法创建日志文件?
pytest运行日志测试时AssertionError问题解决
问题
手动执行$ python -m mylog可正常生成日志文件,但通过$ pytest -s运行测试时,日志文件未创建,触发AssertionError。
相关代码
mylog.py
import logging def foobar(logfile): logging.basicConfig(filename=logfile, level=logging.DEBUG) logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too') logging.error('And non-ASCII stuff, too, like Øresund and Malmö')
test_mylog.py
from . import mylog from pathlib import Path def test_mylog(): logfile='./mylog.log' mylog.foobar(logfile) assert Path(logfile).exists()
错误信息
AssertionError: 断言结果为False
原因与解决方法
原因
logging.basicConfig()仅在首次调用时生效,pytest运行时会自动配置logging环境(比如添加控制台输出处理器),导致后续调用basicConfig()无法覆盖原有配置,也就不会创建指定的日志文件。
解决方法
方法1:重置logging根处理器后再配置
修改mylog.py的foobar函数,先清除根logger的所有处理器,再调用basicConfig():
import logging def foobar(logfile): # 清除根logger的现有处理器 for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) # 重新配置日志文件 logging.basicConfig(filename=logfile, level=logging.DEBUG) logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too') logging.error('And non-ASCII stuff, too, like Øresund and Malmö')
方法2:手动创建FileHandler(更灵活)
不依赖basicConfig(),直接创建文件处理器并添加到logger,避免受现有配置影响:
import logging def foobar(logfile): logger = logging.getLogger() logger.setLevel(logging.DEBUG) # 清除现有处理器 for handler in logger.handlers[:]: logger.removeHandler(handler) # 创建并添加文件处理器 file_handler = logging.FileHandler(logfile) # 可选:设置日志格式 formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') file_handler.setFormatter(formatter) logger.addHandler(file_handler) logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too') logging.error('And non-ASCII stuff, too, like Øresund and Malmö')
方法3:测试中指定日志配置(可选)
在测试函数中,直接重置logging配置,确保日志文件被创建:
from . import mylog from pathlib import Path import logging def test_mylog(): logfile='./mylog.log' # 重置logging配置 for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) mylog.foobar(logfile) assert Path(logfile).exists()
内容的提问来源于stack exchange,提问作者jjk
相关产品推荐
相关产品推荐

