如何参数化具有多个参数的夹具
How to parametrize a fixture with multiple parameters
我有一个灯具,我想多次使用 request.param
。
@pytest.fixture
def get_settings(request):
with mock.patch("helpers.helpers.get_settings") as mocked_settings:
mocked_settings.return_value = Settings(
TOKEN_KEY=request.param, # <== Here
TOKEN_PASSWORD=request.param) # <== And here
yield
@pytest.fixture
def get_user():
return User(name="Test User")
def generate_new_token(user: User) -> str:
settings = get_settings()
private_key = settings.TOKEN_KEY
token_password = settings.TOKEN_PASSWORD
if not private_key.strip():
raise ValueError("Private key must not be empty")
我该怎么做?如果我像上面那样做(有两个 request.param
),然后像这样在我的测试函数中使用它:
@pytest.mark.parametrize('get_settings, expected', [(FAKE_TOKEN_KEY, '', None), (FAKE_TOKEN_KEY, '1', None)],
indirect=["get_settings"])
def test_generate_new_token(get_user, get_settings, expected):
assert generate_new_token(user=get_user) == expected
我收到这个错误:
in "parametrize" the number of names (2): ['get_settings',
'expected'] must be equal to the number of values (3)
我不确定它是否与我正在传递给测试函数的第二个夹具 (get_user
) 有关。但是我该如何解决呢?
更新
None
是期望值,我把另外两个放在元组中。但在这种情况下,我得到以下错误:
test setup failed
request = <SubRequest 'get_settings' for <Function test_generate_new_token[get_settings1-None]>>
@pytest.fixture
def get_settings(request):
with mock.patch("helpers.helpers.get_settings") as mocked_settings:
> mocked_settings.return_value = Settings(
DEBUG=True,
TOKEN_KEY=request.param, # FAKE_TOKEN_KEY,
TOKEN_PASSWORD=request.param)
../conftest.py:76:
pydantic/env_settings.py:36: in pydantic.env_settings.BaseSettings.init
???
???
E pydantic.error_wrappers.ValidationError: 2 validation errors for Settings
E TOKEN_KEY
E str type expected (type=type_error.str)
E TOKEN_PASSWORD
E str type expected (type=type_error.str)
pydantic/main.py:406: ValidationError
所以我需要在我的代码中做两处更改来解决问题:
1- 我必须在元组中传递参数:
@pytest.mark.parametrize('get_settings, expected', [
((FAKE_TOKEN_KEY, ''), None),
((FAKE_TOKEN_KEY, '1'), None)
],
indirect=["get_settings"])
2- 我必须在夹具中传递参数索引:
@pytest.fixture
def get_settings(request):
with mock.patch("helpers.helpers.get_settings") as mocked_settings:
mocked_settings.return_value = Settings(
TOKEN_KEY=request.param[0], # <== Here I added index [0]
TOKEN_PASSWORD=request.param[1]) # <== And here index [1]
yield
我有一个灯具,我想多次使用 request.param
。
@pytest.fixture
def get_settings(request):
with mock.patch("helpers.helpers.get_settings") as mocked_settings:
mocked_settings.return_value = Settings(
TOKEN_KEY=request.param, # <== Here
TOKEN_PASSWORD=request.param) # <== And here
yield
@pytest.fixture
def get_user():
return User(name="Test User")
def generate_new_token(user: User) -> str:
settings = get_settings()
private_key = settings.TOKEN_KEY
token_password = settings.TOKEN_PASSWORD
if not private_key.strip():
raise ValueError("Private key must not be empty")
我该怎么做?如果我像上面那样做(有两个 request.param
),然后像这样在我的测试函数中使用它:
@pytest.mark.parametrize('get_settings, expected', [(FAKE_TOKEN_KEY, '', None), (FAKE_TOKEN_KEY, '1', None)],
indirect=["get_settings"])
def test_generate_new_token(get_user, get_settings, expected):
assert generate_new_token(user=get_user) == expected
我收到这个错误:
in "parametrize" the number of names (2): ['get_settings', 'expected'] must be equal to the number of values (3)
我不确定它是否与我正在传递给测试函数的第二个夹具 (get_user
) 有关。但是我该如何解决呢?
更新
None
是期望值,我把另外两个放在元组中。但在这种情况下,我得到以下错误:
test setup failed
request = <SubRequest 'get_settings' for <Function test_generate_new_token[get_settings1-None]>> @pytest.fixture def get_settings(request): with mock.patch("helpers.helpers.get_settings") as mocked_settings: > mocked_settings.return_value = Settings( DEBUG=True, TOKEN_KEY=request.param, # FAKE_TOKEN_KEY, TOKEN_PASSWORD=request.param)
../conftest.py:76:
pydantic/env_settings.py:36: in pydantic.env_settings.BaseSettings.init ???
???
E pydantic.error_wrappers.ValidationError: 2 validation errors for Settings E TOKEN_KEY
E str type expected (type=type_error.str)
E TOKEN_PASSWORD
E str type expected (type=type_error.str)
pydantic/main.py:406: ValidationError
所以我需要在我的代码中做两处更改来解决问题:
1- 我必须在元组中传递参数:
@pytest.mark.parametrize('get_settings, expected', [
((FAKE_TOKEN_KEY, ''), None),
((FAKE_TOKEN_KEY, '1'), None)
],
indirect=["get_settings"])
2- 我必须在夹具中传递参数索引:
@pytest.fixture
def get_settings(request):
with mock.patch("helpers.helpers.get_settings") as mocked_settings:
mocked_settings.return_value = Settings(
TOKEN_KEY=request.param[0], # <== Here I added index [0]
TOKEN_PASSWORD=request.param[1]) # <== And here index [1]
yield