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

问题描述 投票:1回答:1

我有一个自定义上下文管理器,我使用(不是夹具)来设置和清理测试:

@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

但是,灯具非常不灵活。我想在每个测试中将不同的参数传递给我的上下文,而使用fixture会迫使我为每个案例定义一个不同的fixture。

python-3.x pytest yield fixtures contextmanager
1个回答
2
投票

如果抛出异常,contextlib不会执行post-yield语句。这是设计的。为了使它工作,你必须写:

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

    try:
        yield instance

    finally:
        db_delete(instance)

在我看来,这是违反直觉的,因为尝试不是关于收益本身。

我采取了contextmanager的实现,并制作了一个安全的版本,按照我的预期工作,但它是一个完整的代码重复,如果有人有一个更好的解决方法,我很乐意看到它。

© www.soinside.com 2019 - 2024. All rights reserved.