繁体   English   中英

Pytest 在拆卸后断言夹具

[英]Pytest asserting fixture after teardown

我有一个测试,可以制作一个东西,验证它,删除它并确认它已被删除。

def test_thing():
    thing = Thing()  # Simplified, it actually takes many lines to make a thing

    assert thing.exists

    thing.delete()  # Simplified, it also takes a few lines to delete it

    assert thing.deleted

接下来我想做更多的测试来使用这个东西,所以很自然的下一步就是把东西的创建/删除移到一个fixture中

@pytest.fixture
def thing():
    thing = Thing()  # Simplified, it actually takes many lines to make a thing
    yield thing
    thing.delete()  # Simplified, it also takes a few lines to delete it

def test_thing(thing):
    assert thing.exists

def test_thing_again(thing):
    # Do more stuff with thing

...

但现在我失去了我的assert thing.deleted

我觉得我在这里有几个选择,但没有一个是令人满意的。

  1. 我可以在夹具中断言,但 AFAIK 将断言放入夹具中是不好的做法,因为如果它失败,它将导致ERROR而不是FAIL
  2. 我可以保留我的原始测试并创建夹具,但这会导致创建/删除事物的大量重复代码。
  3. 我不能直接调用夹具,因为我得到了一个Fixture called directly所以我可以将事物创建移到夹具和测试都使用的生成器中。 但这感觉很笨重,如果我thing夹具需要使用另一个夹具会发生什么?

我在这里最好的选择是什么? 有什么我没有想到的吗?

如果你想测试一个“东西”是否被删除,制作一个不拆卸的夹具,在测试中删除它,然后断言它是否被删除。

@pytest.fixture
def thing_create():
    # Perform all the creation steps
    thing = Thing()
    ...

    yield thing


def thing_delete(thing):
    # Perform all the deletion steps
    ...
    thing.delete()  


@pytest.fixture
def thing_all(thing_create):
    yield thing_create
    thing_delete(thing_create)


def test_thing(thing_all):
    assert thing_all.exists


def test_thing_again(thing_create):
    thing_delete(thing_create)
    assert thing_create.deleted

如何在适当的地方使用夹具(以减少重复),而不是在你的逻辑只存在一次的地方。

@pytest.fixture
def thing():
    thing = Thing()  # Simplified, it actually takes many lines to make a thing
    yield thing
    thing.delete()  # Simplified, it also takes a few lines to delete it

def test_thing(thing):
    assert thing.exists

def test_thing_does_a_thing(thing):
    expected = "expected"
    assert thing.do_thing() == expected

def test_thing_deletes():
    # just don't use the fixture here
    thing = Thing()
    thing.delete()
    assert thing.deleted

另一种解决方案可能是拥有一个生成上下文管理器的单一夹具,因此测试可以完全控制调用它。

@pytest.fixture
def gen_thing():

    @contextmanager
    def cm():
        thing = Thing()  # Simplified, it actually takes many lines to make a thing
        try:
            yield thing
        finally:
            thing.delete()  # Simplified, it also takes a few lines to delete it

    yield cm


def test_thing(gen_thing):
    with gen_thing() as thing:
        assert thing.exists
    assert thing.deleted


def test_thing_again(gen_thing):
    with gen_thing() as thing:
        # Do more stuff with thing

将上下文管理器创建为闭包意味着它也将具有与夹具相同的 scope。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM