python:日志记录和单元测试

python:日志记录和单元测试,python,unit-testing,logging,Python,Unit Testing,Logging,我的项目中的单元测试输出有问题。这不是一个大问题,但我不明白原因,想研究一下 环境: 1) conf.py包含记录器的定义 fh = logging.FileHandler(LOG_FILE_NAME) ff = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - (message)s') fh.setFormatter(ff) ch = logging.StreamHandler() cf = logging.Formatte

我的项目中的单元测试输出有问题。这不是一个大问题,但我不明白原因,想研究一下

环境:

1) conf.py包含记录器的定义

fh = logging.FileHandler(LOG_FILE_NAME)
ff = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - (message)s')
fh.setFormatter(ff)
ch = logging.StreamHandler()
cf = logging.Formatter('%(levelname)s - %(message)s')
ch.setFormatter(cf)

lg = logging.getLogger('logger')
lg.setLevel(LOG_LEVEL)
lg.addHandler(ch)
lg.addHandler(fh)

2) 应用程序的模块从conf导入lg,并使用它收集日志事件

3) 此外,我还为一个应用程序模块添加了unittest

4) 当我运行测试时

python3 -m unittest -v project/tests/test-module.py
我得到了下一个控制台输出:

test_init_ok (project.tests.test-module.TestReportData) ... ok
test_set_report (project.tests.test-module.TestReportData) ... DEBUG - Report is {} ok
我不知道为什么原始sys.stdout(来自conf)的最后一条消息会被发送到unittest流


我也很高兴能得到更好实践的建议。

“应用程序的模块从conf导入lg”=>它们实际上不应该。模块应该只做
导入日志;logger=logging.getLogger()
(通常使用魔法变量
\uuuuu name\uuuuuu
)。此外,您可能需要使用
logging.DictConfig
,它比手动配置更友好。@brunodesshuillers您能解释一下“他们实际上不应该这样做”吗?或者你有推荐信吗?感谢您的“DictConfig”,我刚刚阅读了有关它的文档。日志库工作方式的一个要点是将记录器的使用(库代码)与配置(应用程序)分离。这使得库完全独立于使用它们的应用程序,应用程序可以按照自己的意愿配置日志记录。此外,由于日志记录程序基于名称形成层次结构,并且“root”日志记录程序位于顶部(因此“foo.bar.bazz”是“foo.bar”的子级,而“foo.bar”是“foo”的子级,而“foo”是“root”的子级-因此,规范地使用
\uuuuu name\uuuuu
变量)以及默认情况下,子记录器传播到其父记录器,您只需使用合理的默认值配置根记录器,并根据需要覆盖给定子记录器(及其自己的子记录器)的配置。