[英]Pytest asserting fixture after teardown
I have a test that makes a thing, validates it, deletes the thing and confirms it was deleted.我有一个测试,可以制作一个东西,验证它,删除它并确认它已被删除。
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
Next I want to make many more tests that all use the thing, so it's a natural next step to move the thing creation/deletion into a fixture接下来我想做更多的测试来使用这个东西,所以很自然的下一步就是把东西的创建/删除移到一个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
...
But now I've lost my assert thing.deleted
.但现在我失去了我的
assert thing.deleted
。
I feel like I have a few options here, but none are satisfying.我觉得我在这里有几个选择,但没有一个是令人满意的。
ERROR
instead of a FAIL
.ERROR
而不是FAIL
。Fixture called directly
exception so I could move the thing creation out into a generator that is used by both the fixture and the test.Fixture called directly
所以我可以将事物创建移到夹具和测试都使用的生成器中。 This feels clunky though and what happens if my thing
fixture needs to use another fixture?thing
夹具需要使用另一个夹具会发生什么? What is my best option here?我在这里最好的选择是什么? Is there something I haven't thought of?
有什么我没有想到的吗?
If you want to test that a "thing" is deleted, make a fixture without teardown, delete it in the test, then assert if it is deleted.如果你想测试一个“东西”是否被删除,制作一个不拆卸的夹具,在测试中删除它,然后断言它是否被删除。
@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
How about using the fixture where appropriate (to reduce duplication) but not where your logic only exists once.如何在适当的地方使用夹具(以减少重复),而不是在你的逻辑只存在一次的地方。
@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
Another solution could be to have a single fixture that yields a context manager, so the test can be in full control of invoking it.另一种解决方案可能是拥有一个生成上下文管理器的单一夹具,因此测试可以完全控制调用它。
@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
Creating the context manager as a closure means it would have the same scope as the fixture too.将上下文管理器创建为闭包意味着它也将具有与夹具相同的 scope。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.