pytest fixture总是返回一个函数

Cas*_*ass 7 python testing fixtures pytest

我希望能够将一个值从fixture返回到多个测试/测试类,但传递的值是一个函数.

这是我的代码:

import pytest

@pytest.fixture()
def user_setup():
    user = {
        'name': 'chad',
        'id': 1
    }
    return user

@pytest.mark.usefixtures('user_setup')
class TestThings:
    def test_user(self):
        assert user_setup['name'] == 'chad'
Run Code Online (Sandbox Code Playgroud)

输出是:

=================================== FAILURES ===================================
_____________________________ TestThings.test_user _____________________________

self = <tests.test_again.TestThings instance at 0x10aed6998>

    def test_user(self):
>       assert user_setup['name'] == 'chad'
E       TypeError: 'function' object has no attribute '__getitem__'

tests/test_again.py:14: TypeError
=========================== 1 failed in 0.02 seconds ===========================
Run Code Online (Sandbox Code Playgroud)

但是,如果我重写我的测试,以便它不使用usefixtures装饰器,它按预期工作:

def test_user(user_setup):
    assert user_setup['name'] == 'chad'
Run Code Online (Sandbox Code Playgroud)

当我尝试使用装饰器方法时,为什么它不起作用的任何想法?

Jer*_*len 15

当您使用@pytest.mark.usefixtures标记时,如果希望将该夹具注入到测试函数中,则仍需要提供类似命名的输入参数.

固定装置py.test文档中所述:

稍后可以引用fixture函数的名称以使其在运行测试之前调用...测试函数可以直接使用fixture名称作为输入参数,在这种情况下,将注入从fixture函数返回的fixture实例.

所以只使用@pytest.mark.usefixtures装饰器只会调用该函数.提供输入参数将为您提供该函数的结果.

您只需要@pytest.mark.usefixtures在想要调用fixture时使用它,但又不想将它作为测试的输入参数.如py.test文档中所述.

你得到一个关于user_setup成为一个函数的异常的原因是因为在你的test_user函数中,这个名字user_setup实际上是指你之前在文件中定义的函数.要使代码按预期工作,您需要在test_user函数中添加一个参数:

@pytest.mark.usefixtures('user_setup')
class TestThings:
    def test_user(self, user_setup):
        assert user_setup['name'] == 'chad'
Run Code Online (Sandbox Code Playgroud)

现在从test_user函数的角度来看,名称user_setup将引用函数参数,该参数将是py.test注入的fixture的返回值.

但实际上你根本不需要使用@pytest.mark.usefixtures装饰器.

  • 感谢您对其工作原理的明确解释.我想我可以完成这个,而不必将参数添加到我的测试类中的每个测试函数. (2认同)