【问题标题】:How does pytest deal with fixtures calling other fixtures?pytest 如何处理调用其他夹具的夹具?
【发布时间】:2018-07-01 03:17:59
【问题描述】:

我有两个 pytest 设备,clientappclient 致电 app

测试函数test_register 有参数clientapp,因此调用了这两个fixture。

我的问题是,test_register 中使用的app 实例是否总是client 调用的实例,如果这就是 pytest 通常的工作方式(test_register 中的断言通过,所以在这个案例) 。

换句话说,pytest 是为调用fixture 的测试函数中的每个参数生成不相关的实例,还是调用fixture 并且返回的实例也相互引用?

代码如下:

@pytest.fixture
def app():
    app = create_app({
        'TESTING': True,
    })

    yield app


@pytest.fixture
def client(app):
    return app.test_client()



def test_register(client, app):
    assert client.application is app

【问题讨论】:

  • 就您的问题而言,fixture 只是在测试开始前会调用您的函数,因此您不必自己动手,可以立即开始使用它们的结果。他们的结果存储在测试“生存”期间(function 范围)。我猜你害怕的是app() 会被调用两次,一次在client(),然后再次在test_register(),但这不是它的工作原理。 app 将在第一次请求时调用一次,其结果的引用将被存储并传递给 client()test_register(),因此您可以依赖它。
  • 但是,请注意,如果您要进行其他测试,例如def test_unregister(app),那么两个测试中的 app 实例将不同 - 这是由夹具中的 scope 设置调节的。默认情况下,scope 设置为function,因此在不同的测试之前会再次调用fixture;如果将scope 设置为session,则每次测试运行都会调用一次fixture,并且所有测试函数都将获得相同的app 实例。
  • 谢谢,这正是我要问的!我想知道app 是否会被调用两次,一次是client,一次是test_register,是否会有两个不同的实例。 pytest 文档中是否有一部分对此进行了说明?我查看了它,但找不到任何东西。
  • 我不知道这是否在文档中的某处明确说明,但是将固定装置作为测试参数传递是依赖注入的一种实现,这就是 DI 通常的工作方式(尽管不是必须的)。考虑一个应该运行一些繁重的计算并返回结果或打开并返回数据库连接的夹具,如果它们被重复而不被重用,那将是一场灾难!

标签: python python-3.x pytest


【解决方案1】:

所有灯具都有一个作用域,隐含作用域是function,但也有classmodulesession 作用域。在每个范围内,只会创建一个固定装置的实例。

因此,在您的示例中,appclient 都在使用函数范围。执行test_register 时,它会进入此测试的功能范围并创建夹具实例。因此test_registerclient 都得到app 的相同实例。

请参阅the docs,了解有关这一切如何运作的更多详细信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多