6

我正在使用 py.test 来测试我的一些模块,其中包含相当多的 stdlib 日志记录。我当然希望日志记录到 py.test 捕获的 stdout,这样如果测试失败,我将获得所有相关的日志记录消息。

这样做的问题是,在 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 集成的正确方法?

(我试着看看这个,它看起来应该可以正常工作,所以它对我没有多大帮助)

4

3 回答 3

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

于 2011-01-22T14:21:46.297 回答
3

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

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

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

于 2011-01-21T19:23:26.873 回答
-1

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

于 2011-01-18T13:36:08.773 回答