简体   繁体   English

在单元测试中隐藏stderr输出

[英]Hide stderr output in unit tests

I'm writing a few unit tests of some code which uses sys.stderr.write to report errors in input. 我正在编写一些代码的单元测试,这些代码使用sys.stderr.write来报告输入中的错误。 This is as it should be, but this clobbers the unit test output. 这是应该的,但这会破坏单元测试输出。 Is there any way to tell Python to not output error messages for single commands, à la 2> /dev/null ? 有没有办法告诉Python不输出单个命令的错误消息,àla2 2> /dev/null

I suggest writing a context manager: 我建议写一个上下文管理器:

import contextlib
import sys

@contextlib.contextmanager
def nostderr():
    savestderr = sys.stderr
    class Devnull(object):
        def write(self, _): pass
        def flush(self): pass
    sys.stderr = Devnull()
    try:
        yield
    finally:
        sys.stderr = savestderr

Now, wrap any code snippet whose stderr you want suppressed in a with nostderr(): and you have the localized, temporary, guaranteed-reversible stderr suppression that you want. 现在, with nostderr():包装您想要抑制其stderr的任何代码片段with nostderr():并且您具有所需的本地化,临时,保证可逆的stderr抑制。

You could create a dummy file object that did nothing with its output, and set stderr to that: 您可以创建一个对其输出不执行任何操作的虚拟文件对象,并将stderr设置为:

class NullWriter:
    def write(self, s):
        pass

sys.stderr = NullWriter()

If you only want to quiet stderr for a specific duration, you can use a with statement like so: 如果你只想在特定的持续时间内安静stderr,你可以像这样使用with语句:

class Quieter:
    def __enter__(self):
        self.old_stderr = sys.stderr
        sys.stderr = NullWriter()

    def __exit__(self, type, value, traceback):
        sys.stderr = self.old_stderr

with Quieter():
    # Do stuff; stderr will be suppressed, and it will be restored
    # when this block exits

Requires Python 2.6 or higher, or you can use it in Python 2.5 with a from __future__ import with_statement . 需要Python 2.6或更高版本,或者您可以在Python 2.5中使用from __future__ import with_statement

Another possibility (besides assigning to sys.stderr ) is to structure your code to write errors to a file provided, but to default that file to sys.stderr. 另一种可能性(除了分配给sys.stderr之外)是构造代码以将错误写入提供的文件,但将该文件默认为sys.stderr。 Then you can provide a DevNull writer during testing. 然后,您可以在测试期间提供DevNull编写器。

If you do want to reassign sys.stderr, you can use the unittest framework to manage it for you: 如果您确实想重新分配sys.stderr,可以使用unittest框架为您管理它:

class DevNull(object):
    def write(self, data): 
        pass

class MyTestCase(unittest.TestCase):
    def setUp(self):
        self.old_stderr = sys.stderr
        sys.stderr = DevNull()

    def tearDown(self):
        sys.stderr = self.old_stderr

This way, every test dev-null's stderr, but then restores it at the end of the test. 这样,每个测试dev-null的stderr,但然后在测试结束时恢复它。

class DevNull(object):
    def write(self, data): pass

sys.stderr = DevNull()

To have a less permanent solution, one could figure out something like as follows: 为了获得一个不那么永久的解决方案,可以找出类似如下的内容:

_stderr = None
def quiet():
    global _stderr
    if _stderr is None:
        _stderr = sys.stderr
        sys.stderr = DevNull()

def verbose():
   global _stderr
   if _stderr is not None:
       sys.stderr = _stderr
      _stderr = None

Function names can probably be better 函数名称可能更好

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

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