我想为一组测试编写自定义记录器,而不对测试进行任何重大更改。我想使用类似于夹具的东西,我可以将其传递给测试方法,夹具在整个测试过程中在后台运行,捕获stdout和stderr并将其更改为自定义消息。怎么办呢?
def test_1():
blah
blah
print('Some msg')
blah
assert something, assert_msg
Output:
Some msg (if assert fails, then assertion error too)
我想要的是
@fixture
def logger():
capture stdout, stderr
custom_msg = cust_msg(stdout, stderr)
print(custom_msg)
def test_1(logger):
blah
blah
print('Some msg')
blah
assert something, assert_msg
Output:
Custom msg (if assert fails, then custom assertion error too)
答案 0 :(得分:0)
您无法从模块中捕获标准输出,无需重新定义sys.stdout
或print
。重新定义打印更容易,因为它已经是一个功能。要抓住失败的assert
,只需抓住AssertionError
s。
import functools
import sys
def fixture(f):
old_print = print
@functools.wraps(f)
def wrapped(*args, **kwargs):
global print
def print(*value, sep=' ', end='\n', file=sys.stdout, flush=False):
msg = sep.join(map(str, value)) + end
# Manipulate msg here
file.write(manipulated)
if flush:
file.flush()
try:
return f(*args, **kwargs)
except AssertionError as e:
# Custom message on failed assertion
msg = e.args[0] if len(e.args) == 1 else None
old_print(manipulated)
finally:
print = old_print
return wrapped
但是,assert
并不能提供更多有用的信息。我会使用一个实际的测试库,比如unittest
。
另一种方法是将其作为子流程运行。