如何将stdlib日志记录与py.test结合使用

时间:2011-01-18 12:36:49

标签: python unit-testing logging pytest

我正在使用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,它看起来应该没有问题,所以它对我帮助不大)

3 个答案:

答案 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] http://pypi.python.org/pypi/pytest-capturelog/0.7

答案 1 :(得分:3)

如果您不介意在py.test丢弃对象之后无法进行日志记录,您可以在模块或测试的早期某处将模块级变量logging.raiseExceptions设置为False

这将使日志记录模块吞下日志记录子系统中发生的异常。 (对于生产系统而言,这是一个很好的做法,您不希望在日志记录中出现错误导致系统崩溃)

您还可以使用logging.basicConfig()将日志记录输出设置为单独的文件。但这可能不是你想要的。

答案 2 :(得分:-2)

您需要做的就是将-s选项传递给py.test,以便它不会捕获标准输出。