簡體   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