我希望能够将一个值从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'
输出结果为:
=================================== 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 ===========================
但是如果我重写我的测试以便它不使用usefixtures
装饰器,它会按预期工作:
def test_user(user_setup):
assert user_setup['name'] == 'chad'
当我尝试使用装饰器方法时,为什么它不起作用的任何想法?
答案 0 :(得分:14)
当您使用@pytest.mark.usefixtures
标记时,如果您希望将该fixture添加到测试函数中,则仍需要提供类似命名的输入参数。
以后可以引用fixture函数的名称来引起它 在运行测试之前调用...测试函数可以直接使用 夹具名称作为输入参数,在这种情况下夹具实例 从夹具函数返回将被注入。
所以只使用@pytest.mark.usefixtures
装饰器只会调用该函数。提供输入参数将为您提供该函数的结果。
当你想要调用一个fixture但你不想将它作为测试的输入参数时,你真的需要使用@pytest.mark.usefixtures
。如py.test docs中所述。
你得到一个关于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'
现在从test_user函数的角度来看,名称user_setup
将引用函数参数,该参数将是py.test注入的fixture的返回值。
但实际上你根本不需要使用@pytest.mark.usefixtures
装饰器。
答案 1 :(得分:-1)
在这两种情况下,在全局范围user_setup
中引用该函数。不同之处在于,在你的nonfixture版本中,你正在创建一个具有相同名称的参数,这是一个混淆的经典方法。
在该非修复版本中,在test_user
范围内,您的user_setup
标识符指的是您传递它的任何内容,而不是全局范围内的函数。
我认为您可能打算调用user_setup
并将结果下标为
assert user_setup()['name'] == 'chad'