当断言失败时,Pytest跳过了contextmanager的post yield

时间:2018-09-12 05:23:47

标签: python-3.x pytest yield fixtures 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()代码(即后屈服语句)将不会执行。

我可以看到,如果我使用灯具,它确实可以工作。

@pytest.fixture
def db_instance():
    instance = db_insert( ... )

    yield instance

    db_delete(instance)

def test_my_test(db_instance):
        #  ...
        assert result

但是,固定装置非常不灵活。我想在每次测试中将不同的参数传递给我的上下文,而使用夹具会迫使我为每种情况定义不同的夹具。

1 个答案:

答案 0 :(得分:2)

如果抛出异常,

contextlib将不执行后屈服语句。这是设计使然。要使其工作,您必须编写:

@contextmanager
def db_content(*args, **kwargs):
    instance = db_insert( ... )

    try:
        yield instance

    finally:
        db_delete(instance)

我认为这是违反直觉的,因为尝试并不针对收益率本身。

我采用了contextmanager的实现,并制作了一个安全版本,该版本可以按我的预期工作,但是如果有人有更好的解决方法,我希望看到它,这是一个完整的代码重复。