我有这个示例代码(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()
这给了我以下输出:
» 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)
但是由于被测程序产生的冗长,恼人的消息(真正的程序产生很多输出),我无法看到unittest的输出。我想摆脱正在测试的函数(give_me_5
)的stdout / stderr,但我仍然希望看到unittest
的stdout / stderr。我想得到这个结果:
» 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)
因此,被测程序(stdout和stderr)产生的输出被unittest过滤掉,但是unittest本身产生的输出保持。我不想修改被测试的代码(代码本身没有重定向)。我只想告诉unittest所有被测试代码生成的stdout / stderr输出都应该被丢弃。
这可能吗?
答案 0 :(得分:5)
@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')
输出:
I am here
I am back
答案 1 :(得分:4)
暂时将body.home #header {
z-index: 10;
}
和sys.stdout
替换为类似文件的实例。例如,您可以使用StringIO
也称为内存缓冲区。
sys.stderr
您可能希望添加异常处理,甚至可以在上下文管理器中将此代码转换为重用
答案 2 :(得分:0)
供参考(以及获取评论),这是我最终使用的代码(受到@Alik的回复启发):
import sys
def give_me_5():
print >>sys.stdout, "A long annoying output message"
print >>sys.stderr, "A long annoying error message"
return 6
import unittest
def redirect(stdout_file=None, stderr_file=None):
new_stdout = open(stdout_file, 'w') if stdout_file else None
new_stderr = open(stderr_file, 'w') if stderr_file else None
if new_stdout : sys.stdout = new_stdout
if new_stderr : sys.stderr = new_stderr
def redirect_testcase(test_case):
logfile = '.'.join([test_case.__module__, test_case.__class__.__name__, 'out'])
errfile = '.'.join([test_case.__module__, test_case.__class__.__name__, 'err'])
redirect(logfile, errfile)
class TestMe(unittest.TestCase):
def setUp(self):
redirect_testcase(self)
def test_give_me_5(self):
self.assertEqual(give_me_5(), 5)
if __name__ == '__main__':
unittest.main()
现在只需执行redirect_testcase(self)
,stdout / stderr就会重定向到test_it.TestMe.out
/ test_it.TestMe.err
,并且unittest的输出在控制台stdout / stderr中可见(并且可以重定向)如果需要可以通过shell。
存在一个问题(我还不知道如何修复):特定TestCase中的所有测试都将覆盖.out
/ .err
个文件。最好为每个测试打开一个不同的out / log文件(而不是每个TestCase的常用文件)