Python 如何通过命令行将多个列表参数传递给多个pytest装置

Python 如何通过命令行将多个列表参数传递给多个pytest装置,python,python-3.x,pytest,Python,Python 3.x,Pytest,我想将下面的列表从我的命令行传递到我的pytest代码(比如python中的argparser),有人能帮我怎么做吗 pytest-vs test_sample.py--html=results.html--A_list=['A1','A2']--B_list=['B1']--C_list=['C1','C2'] 这是我的pytest代码 import pytest @pytest.fixture(scope="session", params=A_list) # here

我想将下面的列表从我的命令行传递到我的pytest代码(比如python中的argparser),有人能帮我怎么做吗

pytest-vs test_sample.py--html=results.html--A_list=['A1','A2']--B_list=['B1']--C_list=['C1','C2']

这是我的pytest代码

import pytest

@pytest.fixture(scope="session", params=A_list) # here A_list is a list and it has to be passed from command line
def get_A_list(request):
    print("inside fixture get_A_list - element in A_list: ".format(request.param))
    yield request.param


@pytest.fixture(scope="module", params=B_list) # here B_list is a list and it has to be passed from command line
def get_B_list(request, get_A_list):
    print("inside fixture get_B_list - element in A_list: {}, element in B_list: {}: ".format(get_A_list, request.param))
    yield request.param


@pytest.mark.parametrize("c", C_list) # here C_list is a list and it has to be passed from command line
def test_functionality(get_A_list, get_B_list, c):
    print("inside function test_functionality - element in A_list: {}, element in B_list: {}, element in C_list: {}: ".format(get_A_list, get_B_list, c))
测试功能是我的测试用例功能。测试用例的数量应该基于在命令行中传递的列表的长度

对于上述列表,它必须按照以下顺序执行测试用例

test_functionality[A1-B1-C1]
test_functionality[A1-B1-C2]
test_functionality[A2-B1-C1]
test_functionality[A2-B1-C2]
我需要在**fixture get_A_list中使用A_list中的元素执行一些操作……类似地,我需要在fixtureget_B_list中使用A_list和B_list中的元素执行一些操作。……像这样,我有4个fixture,最后我需要在test_功能中执行测试用例,该功能将使用A_列表、B_列表、C_列表等中的元素

最后,输出应如下所示

    inside fixture get_A_list - element in A_list: A1
    inside fixture get_B_list - element in A_list: A1, element in B_list: B1
    inside function test_functionality - element in A_list: A1, element in B_list: B1, element in C_list: C1
    inside function test_functionality - element in A_list: A1, element in B_list: B1, element in C_list: C2
    inside function test_functionality - element in A_list: A1, element in B_list: B1, element in C_list: C3
    inside fixture get_A_list - element in A_list: A2
    inside fixture get_B_list - element in A_list: A2, element in B_list: B1
    inside function test_functionality - element in A_list: A2, element in B_list: B1, element in C_list: C1
    inside function test_functionality - element in A_list: A2, element in B_list: B1, element in C_list: C2
    inside function test_functionality - element in A_list: A2, element in B_list: B1, element in C_list: C3

这里的问题是,
params
参数是在加载时读取的,其中关于命令行参数的信息还不可用,因此不能像示例中那样设置它们

最好的方法是适当地重新构造代码,这样就不需要了。如果你能做到这一点,那么你就不需要额外的固定装置

无论如何,首先必须注册命令行参数:

conftest.py

def pytest\u addoption(解析器):
addoption(“--A_列表”,action=“store”)
parser.addoption(“--B_list”,action=“store”)
addoption(“--C_list”,action=“store”)
现在,如果可以重新构造代码,使fixture不依赖于参数,那么可以根据传递的命令行参数对测试进行参数化。如果以逗号分隔的列表形式传递参数,则可以执行以下操作:

test.py

导入pytest
@pytest.hookimpl
def pytest_generate_测试(metafunc):
#使用值收集设备名称
选项_值={
“a”:metafunc.config.option.a_列表,
“b”:metafunc.config.option.b_列表,
“c”:metafunc.config.option.c_列表
}
#为每个装置名称添加参数化
对于名称,选项_values.items()中的值:
如果metafunc.fixturenames和value中的名称不是None:
metafunc.Parameterize(名称、值、拆分(“,”))
def测试功能1(a、b、c):
印刷品(a、b、c)
这将按所需顺序创建参数化测试

如果不可能,您可以尝试在运行时创建装置(有关更多信息,请参阅):

conftest.py

#定义用作固定装置的功能
def a_列表_夹具(请求):
打印(f“获取列表:{request.param}”)
屈服请求参数
def b_列表固定装置(请求,获取A_列表):
打印(f“get_B_list:{get_A_list},{request.param}”)
屈服请求参数
#在会话开始时,使用正确的参数创建设备
def pytest_会话启动(会话):
a_list=session.config.option.a_list
如果有一份清单:
a_list=a_list.split(“,”)
name=“获取列表”
fn=pytest.fixture(scope='session',name=name,
参数=一个列表(一个列表)
setattr(sys.modules[__name__],“{}_func.”格式(名称),fn)
b_list=session.config.option.b_list
如果b_列表:
b_list=b_list.split(“,”)
name=“获取列表”
fn=pytest.fixture(scope='session',name=name,
参数=b_列表(b_列表)
setattr(sys.modules[__name__],“{}_func.”格式(名称),fn)
请注意,您仍然需要如上所述对
c
的函数进行参数化:

test.py

导入pytest
@pytest.hookimpl
def pytest_generate_测试(metafunc):
c_值=metafunc.config.option.c_列表
如果metafunc.fixturenames和value中的“c”不是None:
元函数参数化(“c”,value.split(“,”))
def测试功能(获取列表、获取列表、c):
打印(f“测试功能{get_A_list},{get_B_list},{c}”)
这将创建所需的参数化测试:

pytest-vv--A_list=“A1,A2”--B_list=“B1”--C_list=“C1,C2”

请注意,参数顺序不是所需的,但这只是一个表面问题。以下是
打印
功能的输出:

pytest-s--A_list=“A1,A2”--B_list=“B1”--C_list=“C1,C2”


谢谢@MrBean不来梅。。。。。。这并没有解决我的问题。。。。我需要使用列表中的元素在fixture get_A_列表中执行一些操作。。。。。。。。。类似地,我需要在fixture get_B_list中使用A_list和B_list中的元素执行一些操作……。像这样,我有4个fixture,最后我需要在test_功能中执行测试用例,它将使用A_list、B_list、C_list中的元素。。。。。。。。我已经用最终输出和执行顺序更新了我的问题。我添加了一个更复杂的选项来实现这一点(尽管我在中保留了第一个答案,因为这对于大多数情况来说已经足够了)。谢谢Bean先生,我将实现您的第二个答案,看看它是否解决了我的问题。我将检查是否有任何需要的修改来实现我的输出以及订单…这只是一个小例子,但实际上我必须在test_功能中执行大约60个测试用例,在此之前,我需要做一些操作(计划在多个装置中涵盖这些操作),谢谢MrBean。除了参数顺序外,它工作正常,但不是一个函数。正如你提到的,这是一个表面问题。根据您的解决方案,我添加了几个参数以从命令行传递。再次感谢您的解决方案
================================================= test session starts =================================================
...
collected 4 items

so/cmd_line_args/test.py::test_functionality[C1-A1-B1] PASSED                                                    [ 25%]
so/cmd_line_args/test.py::test_functionality[C2-A1-B1] PASSED                                                    [ 50%]
so/cmd_line_args/test.py::test_functionality[C1-A2-B1] PASSED                                                    [ 75%]
so/cmd_line_args/test.py::test_functionality[C2-A2-B1] PASSED                                                    [100%]

================================================== 4 passed in 0.28s ==================================================
================================================= test session starts =================================================
...
collected 4 items

test.py get_A_list: A1
get_B_list: A1,  B1
test_functionality A1, B1, C1
.test_functionality A1, B1, C2
.get_A_list: A2
get_B_list: A2,  B1
test_functionality A2, B1, C1
.test_functionality A2, B1, C2
.

================================================== 4 passed in 0.27s ==================================================