【问题标题】:How to parametrize a fixture with multiple parameters如何对具有多个参数的夹具进行参数化
【发布时间】:2021-11-11 18:19:30
【问题描述】:

我有一个夹具,我想多次使用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

我收到此错误:

在“参数化”中名称的数量(2):['get_settings', 'expected'] 必须等于值的数量 (3)

我不确定它是否与我传递给测试功能的第二个夹具 (get_user) 有关。但是我该如何解决呢?

更新

None 是预期值,我将另外两个放在元组中。但在这种情况下,我收到以下错误:

测试设置失败

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:在 pydantic.env_settings.BaseSettings.init ???


???

E pydantic.error_wrappers.ValidationError:设置的 2 个验证错误 E TOKEN_KEY

预期 E str 类型 (type=type_error.str)

E TOKEN_PASSWORD

预期 E str 类型 (type=type_error.str)

pydantic/main.py:406: 验证错误

【问题讨论】:

  • 不,这与parametrize中的值的个数有关,这2个变量(get_settingsexpected)与3个值(FAKE_TOKEN_KEY'1',@)不匹配987654333@).
  • @MrBeanBremen 这就是我想不出正确方法的地方。在我观看的所有教程中,夹具中只有一个 request.param 并且有效。但就我而言,我需要不止一个,我正在寻找一种方法来做到这一点。
  • 嗯,好的。您可以将元组作为请求参数传递,就像您尝试做的那样,但我在您的装饰器中看不到 expected 参数值。另外,如果你传递一个元组,你必须通过request.param中的索引来访问元组中的值。
  • 如果None 是预期值(刚刚意识到它可能是),那么您只是忘记在元组周围加上括号,例如[((FAKE_TOKEN_KEY, ''), None), ...].
  • 你没有像我写的那样改变元组param的用法,你需要像TOKEN_KEY=request.param[0]TOKEN_PASSWORD=request.param[1]这样的东西。

标签: python pytest fixtures parametrized-testing


【解决方案1】:

因此,我需要在代码中进行两项更改以解决问题:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-08
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    相关资源
    最近更新 更多