我得到了一个简单的测试代码:
test_assert.py
import helper
def test_assert():
assert helper.find_event(helper.HelperEvents("event","this is info")) is True
helper.py
helper_list = []
class HelperEvents:
def __init__(self, event, info):
self.event = event
self.info = info
def add_event(event):
helper_list.append(event)
def find_event(event):
try:
helper_list.index(event, 0, 100)
except ValueError:
return False
return True
这会给我一个像这样的AssertionError:
def test_assert():
> assert helper.find_event(helper.HelperEvents("event","this is info")) is True
E AssertionError: assert False is True
E + where False = <function find_event at 0x158c9b0>(<test_asserts.helper.HelperEvents instance at 0x157d488>)
E + where <function find_event at 0x158c9b0> = helper.find_event
E + and <test_asserts.helper.HelperEvents instance at 0x157d488> = <class test_asserts.helper.HelperEvents at 0x1670188>('event', 'this is info')
E + where <class test_asserts.helper.HelperEvents at 0x1670188> = helper.HelperEvents
test_assert.py:5: AssertionError
但我真的想简化这样的事情: AssertionError:事件:事件信息:这是在列表中找不到的信息
为此,我制作了一个 init .py文件
import pytest
pytest.register_assert_rewrite('test_asserts')
和conftest.py文件:
import pytest
@pytest.hookimpl(tryfirst=True)
def pytest_assertrepr_compare(op, left, right):
print "Left:", left
print "op:", op
print "Right:", right
return [str(left), op, str(right)]
这给了我以下内容:
def test_assert():
> assert helper.find_event(helper.HelperEvents("event","this is info")) is True
E assert False
E is
E True
test_assert.py:5: AssertionError
当我只看到find_event调用的结果时,如何从事件中提取信息?
答案 0 :(得分:0)
所以我最终为pytest_runtest_makereport实现了一个钩子。 我重用pytests实现中的代码并使用我自己的自定义断言表示扩展它。 它看起来像这样:
import pytest
from _pytest._code.code import ExceptionInfo
from _pytest.outcomes import skip
from _pytest._code.code import ReprTraceback, ReprEntry, ReprFileLocation, Traceback
from _pytest.runner import TestReport
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_makereport(item, call):
when = call.when
duration = call.stop - call.start
keywords = dict([(x, 1) for x in item.keywords])
excinfo = call.excinfo
sections = []
if not call.excinfo:
outcome = "passed"
longrepr = None
else:
if not isinstance(excinfo, ExceptionInfo):
outcome = "failed"
longrepr = excinfo
elif excinfo.errisinstance(skip.Exception):
outcome = "skipped"
r = excinfo._getreprcrash()
longrepr = (str(r.path), r.lineno, r.message)
else:
outcome = "failed"
if call.when == "call":
longrepr = custom_excinfo_repr(excinfo) # This creates my custom assert representation
else: # exception in setup or teardown
longrepr = item._repr_failure_py(excinfo,
style=item.config.option.tbstyle)
for rwhen, key, content in item._report_sections:
sections.append(("Captured %s %s" % (key, rwhen), content))
if longr
def beautify_exc_output(lines):
out = []
if any("helper.find_event" in s for s in lines):
out = parseAssert(lines)
return out
def parseAssertion(lines):
assertionType = ""
args = []
out = []
compare = []
# extract data from input
for line in lines:
line = line.strip("+ ")
if "AssertionError" in line:
assertionType = line[line.find("assert"):]
compare = [int(s) for s in assertionType.split() if s.isdigit()] # Check if assertion was an integer compare
if "HelperEvents" in line and "where" not in line:
content = line[line.find("(")+1:line.find(")")] # Find content of event
args = [x.strip(" '") for x in content.split(",")] # split in to args
# Generate output
if len(args) > 1 and len(assertionType) > 0:
Indent = " "
out.append("Assertion error in HelperEvents:")
out.append("###############################################################")
if len(compare) == 2:
out.append(" Expected {0} times {1} but got {2} times".format(compare[1], args[0], compare[0]))
out.append(" " + GetAssertionEvent(assertionType))
out.append(Indent + "Event: {}".format(args[0]))
out.append(Indent + "Info: {}".format(args[1]))
out.append("###############################################################")
return out
def GetAssertionEvent(AssertionType):
if "assert not False" in AssertionType or \
"assert True is False" in AssertionType or \
"assert True" in AssertionType:
return "Unexpected event has been received"
elif "assert False" in AssertionType or \
"assert False is True" in AssertionType:
return "Expected event was not received"
else:
return AssertionType
现在所有这些代码都放在conftest.py中。 如果断言是一种通过实现无法识别的类型,它将从我的钩子返回None,这将使pytest使用默认实现。