在pytest中,fixture和yield_fixture的区别是什么?

42

我正在学习pytest的固件,下面这段代码看起来很相似,最新的看起来也很相似。

是的,在yield_fixture中可读性更好,但是有人能告诉我具体的区别吗?

在像下面提到的情况下,我应该使用哪个?

@pytest.fixture()
def open_browser(request):
    print("Browser opened")

    def close_browser():
        print("browser closed")

    request.addfinalizer(close_browser)

    return "browser object"

@pytest.yield_fixture()
def open_browser():
    print("Browser opened")
    yield "browser object"
    print("browser closed")


def test_google_search(open_browser):
    print(open_browser)
    print("test_google_search")

一个 yield fixture 使得在 fixtures 中使用上下文管理器更加自然。 - anthony sottile
3
从pytest 3.0.0(2016-08-18)开始,使用带有yield语句的@pytest.fixture是编写拆卸代码的首选方式,而@pytest.yield_fixture已被弃用(但尚未删除)。在此处阅读更多信息:https://docs.pytest.org/en/6.2.x/changelog.html#id1313。 - Yash Nag
2个回答

32
唯一的区别在于可读性。我认为(虽然我不确定)其基础行为是相同的(即,在运行yield语句后进行清理的行为像终结器一样)。我总是更喜欢使用yield fixtures进行清理,因为它更易读。
如果您使用的是pytest <3.0,则仍需要使用pytest.yield_fixture才能获得该行为。但是,如果您能够使用pytest 3.0+,则pytest.yield_fixture已弃用,您可以使用pytest.fixture来获得相同的yield_fixture行为。
这里是说明文档
自pytest-3.0以来,使用普通fixture装饰器的fixture可以使用yield语句提供fixture值并执行拆卸代码,就像先前版本中的yield_fixture一样。
标记函数作为yield_fixture仍然受支持,但已弃用,并且不应该在新代码中使用。

1
错误的。请查看 https://github.com/pytest-dev/pytest/issues/2508,以查看如果设置失败,则yield不会拆除。 - Jinglesting

14

addfinalizer 与 yield 相比有两个主要的不同之处:

  1. 可以注册多个 finalizer 函数。
  2. 无论 fixture 的设置代码是否抛出异常,finalizer 都将被调用。这对于正确关闭由夹具创建的所有资源非常方便,即使其中一个资源无法正常创建/获取。

来自pytest文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接