我试图在断言发生时以及在调用任何清理代码之前捕获尽可能多的信息。 下面是我们大多数现有测试的简化代码:
在我的conftest.py中:
import pytest
from datetime import datetime
def pytest_runtest_makereport(item, call):
print('%s: pytest_runtest_makereport(%s)' % (datetime.now(), call))
def pytest_exception_interact(node, call, report):
print('\n%s: pytest_exception_interact' % datetime.now())
在我的测试文件中:
import pytest
from datetime import datetime
@pytest.fixture(scope='function')
def marshall_me():
print('\n%s: starting test' % datetime.now())
yield marshall_me
print('\n%s: ending test' % datetime.now())
class Device(object):
def __enter__(self):
print('\n%s: create object' % datetime.now())
return self
def __exit__(self, type, value, traceback):
print('\n%s: clean-up object' % datetime.now())
def test_fails(marshall_me):
with Device():
assert False
当我跑步时,我得到:
test_fails.py::test_fails 2017-04-26 17:07:37.447359: starting test
2017-04-26 17:07:37.447453: pytest_runtest_makereport(<CallInfowhen='setup' result: []>)
2017-04-26 17:07:37.447583: create object
2017-04-26 17:07:37.448397: clean-up object
2017-04-26 17:07:37.448614: pytest_runtest_makereport(<CallInfowhen='call' exception: assert False>)
FAILED
2017-04-26 17:07:37.462267: pytest_exception_interact
2017-04-26 17:07:37.462353: ending test
2017-04-26 17:07:37.462428: pytest_runtest_makereport(<CallInfo when='teardown' result: []>)
我不能使用pytest_runtest_makereport和pytest_exception_interact,因为它们在清理功能之后被调用,这对我来说收集重要信息已经太晚了。是否有其他类似的函数在实际生成断言时被调用?
答案 0 :(得分:1)
你有断言声明的替代形式:
assert <cond>, <expr>
这意味着解释器首先评估条件,如果错误,它将评估要用作AssertionError
参数的表达式。因此,要在断言失败时调用函数,您可以使用它:
assert condition_to_be_true(), function_to_call_if_not_true()
请注意,function_to_call_if_not_true()
的返回值将用作AssertionError
的参数。如果那不是你想要的,你将需要做一些技巧来改变表达式的结果 - 你可以使用布尔运算符来做到这一点。无论x
是什么,表达式(x and False) or y
将评估为y
(根据python的短路规则)。
要完成它,你可以这样做:
assert condition_to_be_true(), (function_to_call_if_not_true()
and False) or ARGUMENT_TO_AssertionError
另一种方法是滥用语言,如果你必须(这应该被认为是邪恶的)。由于断言语句相当于在确认条件为false之后提升AssertionError
,您可以简单地重新定义它:
class AssertionError(Exception):
def __init__(self, *args, **kwds):
Exception(self, *args, **kwds)
print("Assertion")
assert condition_to_check()
请注意,您需要重新定义AssertionError
语句的当前范围内assert
的值。