我正在使用py.test来测试我的一些模块,其中包含相当多的stdlib日志记录。我当然喜欢将日志记录到stdout,这是由py.test捕获的,这样如果测试失败,我将获得所有相关的日志消息。
这个问题是,在这个对象被py.test丢弃之后,日志记录模块最终尝试将消息记录到py.test 提供的'stdout'对象。也就是说,我得到了:
Traceback (most recent call last):
File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
File "/usr/lib/python2.6/logging/__init__.py", line 1508, in shutdown
h.flush()
File "/usr/lib/python2.6/logging/__init__.py", line 754, in flush
self.stream.flush()
ValueError: I/O operation on closed file
如果我使用-s
关闭捕获,我没有任何问题,但当然这会使测试输出无法通过不相关的日志记录显示。
有人能告诉我将stdlib日志记录与py.test集成的正确方法吗?
(我试着看this,它看起来应该没有问题,所以它对我帮助不大)
答案 0 :(得分:6)
记录/捕获交互是为了更好地处理即将发布的2.0.1版本,您可以通过以下方式将其作为开发快照安装:
pip install -i http://pypi.testrun.org pytest
之后输入“py.test --version”时,你应该至少得到“2.0.1.dev9”。而你发布的问题/错误现在应该消失了。
一些背景知识:日志包坚持“拥有”它使用的流,默认情况下它会抓取sys.stderr并坚持在进程退出时关闭它,通过atexit模块注册。 py.test用一个临时文件替换sys.stdout以便快照输出(包括在文件描述符级别的输出以便也捕获子进程输出)。所以py.test进化到非常小心,总是使用相同的临时文件,因为没有日志记录的atexit-code抱怨。
不是说你也可以安装[pytest-capturelog] [1]插件,这将有助于处理日志输出。
答案 1 :(得分:3)
如果您不介意在py.test丢弃对象之后无法进行日志记录,您可以在模块或测试的早期某处将模块级变量logging.raiseExceptions
设置为False
。
这将使日志记录模块吞下日志记录子系统中发生的异常。 (对于生产系统而言,这是一个很好的做法,您不希望在日志记录中出现错误导致系统崩溃)
您还可以使用logging.basicConfig()
将日志记录输出设置为单独的文件。但这可能不是你想要的。
答案 2 :(得分:-2)
您需要做的就是将-s
选项传递给py.test,以便它不会捕获标准输出。