在单元测试中隐藏stderr输出

l0b*_*0b0 15 python unit-testing

我正在编写一些代码的单元测试,这些代码使用sys.stderr.write来报告输入中的错误.这是应该的,但这会破坏单元测试输出.有没有办法告诉Python不输出单个命令的错误消息,àla 2> /dev/null

Ale*_*lli 24

我建议写一个上下文管理器:

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
Run Code Online (Sandbox Code Playgroud)

现在,将您希望在其中抑制的stderr的任何代码段包装在一起,with nostderr():并且您具有所需的本地化,临时,保证可逆的stderr抑制.


Ada*_*eld 12

您可以创建一个对其输出不执行任何操作的虚拟文件对象,并将stderr设置为:

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

sys.stderr = NullWriter()
Run Code Online (Sandbox Code Playgroud)

如果您只想在特定时间内安静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
Run Code Online (Sandbox Code Playgroud)

需要Python 2.6或更高版本,或者您可以在Python 2.5中使用它from __future__ import with_statement.


Ned*_*der 5

另一种可能性(除了分配sys.stderr)是构造代码以将错误写入提供的文件,但将该文件默认为sys.stderr.然后,您可以在测试期间提供DevNull编写器.

如果您确实要重新分配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
Run Code Online (Sandbox Code Playgroud)

这样,每个测试dev-null的stderr,但然后在测试结束时恢复它.