fixture的返回列表,怎么传入@pytest.mark.parametrize后列表中的数据分多个test执行?

下面两种方法都能将fixture的返回值,传入@pytest.mark.parametrize, 但是结果打印值是整个列表.期望能让列表中的多个元组执行成多个test.这样就能让多种组合分开执行,一次暴露所有问题.

@pytest.fixture
def fixture1():
    return [(1, 'expected1'), (1, 'expected2'), (2, 'expected2')]

@pytest.mark.parametrize('ans', ['fixture1'])
def test_fixture1(ans, request):
    print(request.getfixturevalue(ans))

@pytest.mark.parametrize('ans', [pytest.lazy_fixture('fixture1')])
def test_fixture2(ans):
    print(ans)

测试的实际场景中,这里必须要用fixture函数,因为这个fixture1函数中的处理数据来源于其他的fixture函数.

这种写法可以实现你需要的效果

@pytest.fixture(scope="function", params=[(1, 'expected1'), (1, 'expected2'), (2, 'expected2')])
def fixture1(request):
    return request.param

def test_fixture1(fixture1):
    print(fixture1)

数据 [(1, ‘expected1’), (1, ‘expected2’), (2, ‘expected2’)]不是固定的,这些值实际是从数据库里面拿到的,拿值的过程需要调用其他方法.

可以在其他方法中完成数据库中数据的获取,然后返回值赋值给 params

import pytest

def get_data():
    return [(1, 'expected1'), (1, 'expected2'), (2, 'expected2')]

@pytest.fixture(scope="function", params=get_data())
def fixture1(request):
    return request.param

def test_fixture1(fixture1):
    print(fixture1)

获取数据库值的函数,是需要依赖一个全局的fixture函数的返回,所以不能用普通函数,必须是fixture.在问题中描述了的.
这样的话好像不能通过params传入.

fixture 是不能通过 fixture 传入的, fixture 可以传入到fixture中也可以传到用例中, 参数化一般都是用下面这种方法实现的,要不你再具体描述一下你的场景 ,找找有没有其它的解决方式?

def get_data():
    return [(1, 'expected1'), (1, 'expected2'), (2, 'expected2')]

@pytest.fixture(scope="function", params=get_data())
def fixture1(request):
    return request.param

场景:
数据库里面存了很多数据.需要通过指定的标记来取需要的测试数据.
根据标记从数据库取值并处理后,测试用例中期望在test中同一类别不同数据分开执行.
实现:
现在通过pytest_addoption的hook函数拿到外界给的参数,作为标记, 这个标记通过一个session级别的fixture函数暴露, 取数据是依赖这个标记,所以取数据的函数必须是依赖这个session级别fixture函数的fixture函数.

不知道理解的业务流程对不对
命令行->传入获取数据库数据函数->fixture->用例。
如果是这个路径的话,我觉得你从一开始的设计就有点问题。其实可以按照这个方式去做

命令行参数的传递和获取(conftest.py)

# 定义一个变量(也可以是一个函数的返回值),等下给测试用例使用
database_data = []

# 接受命令行参数
def pytest_addoption(parser):
    # group 将下面所有的 option都展示在这个group下。
    mygroup = parser.getgroup("hogwarts")
    # 注册一个命令行选项
    mygroup.addoption("--database",  # 参数的默认值
                      default='test',  # 存储的变量
                      dest='database',  # 参数的描述信息
                      help='选择数据库')


# 获取命令行信息
def pytest_configure(config):
    # 获取数据库配置信息
    env = config.getoption("--database", default='test')
    tmp = {"env": env}
    # 将数据库配置信息加载到global_env变量中
    database_data.append(tmp)

测试用例调用数据库信息

# 从conftest 调入变量
from CalculatorProject.test.conftest import global_env

# 测试函数使用数据库的数据
def test_demo():
    # 直接在测试方法内调用conftest的变量
    print(global_env)
    assert False

如果想将从数据库获取的数据作为参数化的数据信息,可以如下使用。

@pytest.mark.parametrize("data", global_env)
def test_demo(data):
    # 直接在测试方法内调用conftest的变量
    print(data)
    assert False

如此就可以实现你的需求了,不需要那么绕 fixture调fixture什么的

感谢老师们的解答,问题像剥洋葱一样最终得到解决!