dan*_*ast 5 python stdout stderr python-unittest
我有这个示例代码(test_it.py):
import sys
def give_me_5():
print >>sys.stdout, "STDOUT"
print >>sys.stderr, "STDERR"
return 6
import unittest
class TestMe(unittest.TestCase):
def setUp(self):
pass
def test_give_me_5(self):
self.assertEqual(give_me_5(), 5)
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
这给了我以下输出:
» python -m unittest test_it
A long annoying output message
A long annoying error message
F
======================================================================
FAIL: test_give_me_5 (__main__.TestMe)
----------------------------------------------------------------------
Traceback (most recent call last):
File "xx.py", line 17, in test_give_me_5
self.assertEqual(give_me_5(), 5)
AssertionError: 6 != 5
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)
Run Code Online (Sandbox Code Playgroud)
但由于被测程序产生的长而恼人的消息(真正的程序产生很多输出),我无法看到unittest的输出.我想摆脱正在测试的函数的stdout/stderr(give_me_5),但我仍然希望看到stdout/stderr unittest.我想得到这个结果:
» python -m unittest test_it
F
======================================================================
FAIL: test_give_me_5 (__main__.TestMe)
----------------------------------------------------------------------
Traceback (most recent call last):
File "xx.py", line 17, in test_give_me_5
self.assertEqual(give_me_5(), 5)
AssertionError: 6 != 5
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)
Run Code Online (Sandbox Code Playgroud)
因此,被测程序(stdout和stderr)产生的输出被unittest过滤掉,但是unittest本身产生的输出被保留了.我不想修改被测试的代码(代码本身没有重定向).我只想告诉unittest所有输出到stdout/stderr的输出应该被丢弃.
这可能吗?
@Alik建议是对的.但我想它可以改进.
import sys
# StringIO is replaced in Python 3:
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
class ReplaceStd(object):
""" Let's make it pythonic. """
def __init__(self):
self.stdout = None
self.stderr = None
def __enter__(self):
self.stdout = sys.stdout
self.stderr = sys.stderr
# as it was suggseted already:
sys.stdout = StringIO()
sys.stderr = StringIO()
def __exit__(self, type, value, traceback):
sys.stdout = self.stdout
sys.stderr = self.stderr
print('I am here')
with ReplaceStd():
print('I am not')
print('I am back')
Run Code Online (Sandbox Code Playgroud)
并输出:
I am here
I am back
Run Code Online (Sandbox Code Playgroud)
暂时将sys.stdout和替换sys.stderr为类似文件的实例。例如,您可以使用StringIO又名内存缓冲区。
from StringIO import StringIO
.....
class TestMe(unittest.TestCase):
def setUp(self):
pass
def test_give_me_5(self):
stdout = sys.stdout
stderr = sys.stderr
sys.stdout = StringIO()
sys.stderr = StringIO()
self.assertEqual(give_me_5(), 5)
sys.stdout = stdout
sys.stderr = stderr
Run Code Online (Sandbox Code Playgroud)
您可能想要添加异常处理,甚至将此代码放入上下文管理器中以重用它