简体   繁体   English

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

[英]How can I combine stdlib logging with py.test

I am using py.test to test some modules of mine that contains quite a bit of stdlib logging. 我正在使用py.test来测试我的一些模块,其中包含相当多的stdlib日志记录。 I would of course like for the logging to log to stdout, which is captured by py.test, so that I will get all relevant logging messages if a test fails. 我当然喜欢将日志记录到stdout,这是由py.test捕获的,这样如果测试失败,我将获得所有相关的日志消息。

The problem with this is that the logging module ends up trying to log messages to the 'stdout'-object provided by py.test after this object has been discarded by py.test. 这样做的问题是,在py.test丢弃此对象之后 ,日志记录模块最终尝试将消息记录到py.test提供的'stdout'对象。 That is, I get: 也就是说,我得到:

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

If I turn off capturing with -s , I don't have any problems, but of course that makes the test output unreadable with irrelevant logging. 如果我用-s关闭捕获,我没有任何问题,但当然这使得测试输出与无关的日志记录无法读取。

Can anyone tell me the proper way to integrate stdlib logging with py.test? 谁能告诉我将stdlib日志记录与py.test集成的正确方法?

(I tried looking at this , where it looks like it should just work without issues, so it didn't help me much) (我试着看看这个 ,它看起来应该只是没有问题,所以它对我帮助不大)

Logging/capturing interactions are to better work with the upcoming 2.0.1 release, which you can install already as a development snapshot by: 记录/捕获交互是为了更好地处理即将发布的2.0.1版本,您可以通过以下方式将其作为开发快照安装:

pip install -i http://pypi.testrun.org pytest 

You should get at least "2.0.1.dev9" when you type "py.test --version" afterwards. 之后输入“py.test --version”时,你应该至少得到“2.0.1.dev9”。 And the problem/error your posted should now be gone. 而你发布的问题/错误现在应该消失了。

A bit of background: the logging package insists on "owning" the streams it uses, and by default it grabs sys.stderr and insists to close it at process exit, registered via the atexit module. 一点背景:日志包坚持“拥有”它使用的流,默认情况下它抓取sys.stderr并坚持在进程退出时关闭它,通过atexit模块注册。 py.test substitutes sys.stdout with a temporary file in order to snapshot output (including output at file-descriptor level in order to also catch subprocess output). py.test用一个临时文件替换sys.stdout以便快照输出(包括在文件描述符级别的输出以便也捕获子进程输出)。 So py.test evolved to be very careful to always use the same temporary file as to not have logging's atexit-code complain. 所以py.test进化到非常小心,总是使用相同的临时文件,因为没有日志记录的atexit-code抱怨。

Not that you can also install the [pytest-capturelog][1] plugin which will help some more with dealing with logging output. 并不是说你也可以安装[pytest-capturelog] [1]插件,这将有助于处理日志输出。

[1] http://pypi.python.org/pypi/pytest-capturelog/0.7 [1] http://pypi.python.org/pypi/pytest-capturelog/0.7

If you don't mind the logging going nowhere after the objects have been discarded by py.test you could set the module-level variable logging.raiseExceptions to False somewhere early in your modules or tests. 如果您不介意在py.test丢弃对象之后无法进行日志记录,则可以在模块或测试的早期将模块级变量logging.raiseExceptionsFalse

This will make the logging module swallow exceptions that occur in the logging subsystem. 这将使日志记录模块吞下日志记录子系统中发生的异常。 (Also a good practice for production systems where you don't want errors in logging crash your system) (对于生产系统而言,这是一个很好的做法,您不希望在日志记录中出现错误导致系统崩溃

You could also use logging.basicConfig() to set logging output to a separate file. 您还可以使用logging.basicConfig()将日志记录输出设置为单独的文件。 But this is probably not what you want. 但这可能不是你想要的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM