Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在单元测试中隐藏stderr输出_Python_Unit Testing - Fatal编程技术网

Python 在单元测试中隐藏stderr输出

Python 在单元测试中隐藏stderr输出,python,unit-testing,Python,Unit Testing,我正在编写一些代码的单元测试,这些代码使用sys.stderr.write报告输入中的错误。这是应该的,但这会破坏单元测试输出。有没有办法告诉Python不要为单个命令输出错误消息,比如la2>/dev/null class DevNull(object): def write(self, data): pass sys.stderr = DevNull() 要想找到一个不那么持久的解决方案,我们可以得出如下结论: _stderr = None def quiet(): gl

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

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

sys.stderr = DevNull()
要想找到一个不那么持久的解决方案,我们可以得出如下结论:

_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

函数名可能更好

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

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

sys.stderr = NullWriter()
如果您只想让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
需要Python 2.6或更高版本,或者您可以在Python 2.5中使用它,并使用一个来自uuu future uuu的import with u语句

另一种可能性(除了分配给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

这样,每个测试开发人员都可以使用空的stderr,但在测试结束时会恢复它。

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

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

现在,使用nosterr():将要在
中抑制其stderr的任何代码段包装起来,就可以得到所需的本地化、临时、保证可逆的stderr抑制。

我希望找到一个不太永久的解决方案。没有办法包装像
quiet(…)
这样的命令吗?不需要存储备份。Python已经有一个sys.\uu stderr\uuuu存储备份的原因是没有任何东西是绝对的:谁知道在调用sys.stderr之前是否有其他较大的代码实体更改了sys.stderr?这样,您只需撤消第一个操作。这还有一个好处,如果您愿意,您可以在测试中检查输出。哇!这太棒了。我以前不知道contextlib,因为我仍然使用Python2.4。@shailesh,是的,contextlib有助于编写最简单的上下文管理器(使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。为什么不呢?
sys.stderr=os.devnull
@Matt3o12:因为os.devnull只是一个字符串(例如,在Linux系统上为“/dev/null”),而不是一个文件描述符。