我可以用其他灯具参数化pytest灯具吗?

时间:2017-10-25 20:51:36

标签: python pytest fixtures

我有一个python测试,使用夹具获取凭据(用户ID和密码的元组)

def test_something(credentials)
   (userid, password) = credentials
   print("Hello {0}, welcome to my test".format(userid))

我有凭证的pytest夹具:

@pytest.fixture()
def credentials():
   return ("my_userid", "my_password")

效果很好

现在我想为多个凭证(比如分段和生产)扩展它,以便我的测试将运行两次(每次一次用于分段和生产)。

我认为参数化是答案,但似乎我无法使用灯具进行参数化。

我很乐意做这样的事情:

@pytest.fixture(params=[staging_credentials, production_credentials])
def credentials(request):
    return request.param

其中staging_credentials和production_credentials都是灯具:

@pytest.fixture()
def staging_credentials():
   return ("staging_userid", "staging_password")

@pytest.fixture()
def production_credentials():
   return ("prod_userid", "prod_password")

但显然固定装置的参数可能不是其他装置。

有关如何优雅处理此问题的任何建议?我看过https://docs.pytest.org/en/latest/proposals/parametrize_with_fixtures.html,但这似乎太过暴力了。

谢谢! 史蒂夫

1 个答案:

答案 0 :(得分:3)

间接参数化就是答案。因此,灯具的参数可以是其他灯具(通过其名称/代码)。

import pytest

all_credentials = {
    'staging': ('user1', 'pass1'),
    'prod': ('user2', 'pass2'),
}

@pytest.fixture
def credentials(request):
    return all_credentials[request.param]

@pytest.mark.parametrize('credentials', ['staging', 'prod'], indirect=True)
def test_me(credentials):
    pass

从技术上讲,您不仅可以通过其键获取dict值,还可以基于credentials生成request.param结果,并且此参数将是传递给该参数的同名参数的值。测试

如果你想使用其他灯具(可能是因为设置/拆卸阶段,因为这是唯一的原因):

import pytest

@pytest.fixture
def credentials(request):
    return request.getfuncargvalue(request.param)

@pytest.fixture()
def staging_credentials():
   return ("staging_userid", "staging_password")

@pytest.fixture()
def production_credentials():
   return ("prod_userid", "prod_password")

@pytest.mark.parametrize('credentials', ['staging_credentials', 'production_credentials'], indirect=True)
def test_me(credentials):
    pass

在这里,request.getfuncargvalue(...)将通过夹具名称动态返回夹具值。