【发布时间】:2018-07-01 03:17:59
【问题描述】:
我有两个 pytest 设备,client 和 app。 client 致电 app。
测试函数test_register 有参数client 和app,因此调用了这两个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