Python 在单元测试中隐藏stderr输出
我正在编写一些代码的单元测试,这些代码使用sys.stderr.write报告输入中的错误。这是应该的,但这会破坏单元测试输出。有没有办法告诉Python不要为单个命令输出错误消息,比如laPython 在单元测试中隐藏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
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”),而不是一个文件描述符。