当断言失败时,Pytest 跳过上下文管理器的 post yield
Pytest is skipping post yield of contextmanager when assertion fails
我有一个自定义上下文管理器,我使用它(不是固定装置)来设置和清理测试:
@contextmanager
def db_content(*args, **kwargs):
instance = db_insert( ... )
yield instance
db_delete(instance)
def test_my_test():
with db_content( ... ) as instance:
# ...
assert result
问题是当断言失败时,db_delete()
代码 - 即 post yield 语句不会被执行。
我可以看到,如果我使用固定装置,它确实有效。
@pytest.fixture
def db_instance():
instance = db_insert( ... )
yield instance
db_delete(instance)
def test_my_test(db_instance):
# ...
assert result
但是,固定装置非常不灵活。我想在每次测试时将不同的参数传递给我的上下文,而使用固定装置会迫使我为每种情况定义不同的固定装置。
如果抛出异常,contextlib 不会执行 post-yield 语句。这是设计使然。要让它工作,你必须写:
@contextmanager
def db_content(*args, **kwargs):
instance = db_insert( ... )
try:
yield instance
finally:
db_delete(instance)
在我看来这是违反直觉的,因为尝试不在收益本身上。
我实现了 contextmanager
并制作了一个安全版本,它可以按我的预期工作,但是它是一个完整的代码重复,如果有人有更好的解决方法,我很乐意看到它。
我有一个自定义上下文管理器,我使用它(不是固定装置)来设置和清理测试:
@contextmanager
def db_content(*args, **kwargs):
instance = db_insert( ... )
yield instance
db_delete(instance)
def test_my_test():
with db_content( ... ) as instance:
# ...
assert result
问题是当断言失败时,db_delete()
代码 - 即 post yield 语句不会被执行。
我可以看到,如果我使用固定装置,它确实有效。
@pytest.fixture
def db_instance():
instance = db_insert( ... )
yield instance
db_delete(instance)
def test_my_test(db_instance):
# ...
assert result
但是,固定装置非常不灵活。我想在每次测试时将不同的参数传递给我的上下文,而使用固定装置会迫使我为每种情况定义不同的固定装置。
contextlib 不会执行 post-yield 语句。这是设计使然。要让它工作,你必须写:
@contextmanager
def db_content(*args, **kwargs):
instance = db_insert( ... )
try:
yield instance
finally:
db_delete(instance)
在我看来这是违反直觉的,因为尝试不在收益本身上。
我实现了 contextmanager
并制作了一个安全版本,它可以按我的预期工作,但是它是一个完整的代码重复,如果有人有更好的解决方法,我很乐意看到它。