Передача инструментария pytest в параметризацию

Dec 14 2020

Я получаю следующую ошибку, передавая мое приспособление, определенное в conftest.py в @ pytest.mark.parametrize:

pytest --alist="0220,0221" test_1.py -v -s
NameError: name 'alist' is not defined

conftest.py:

def pytest_addoption(parser):
    parser.addoption("--alist", action="store")

@pytest.fixture
def alist(request):
    return request.config.getoption("--alist").split(",")

test_1.py:

@pytest.mark.parametrize("channel", alist, scope="class")
class TestRaIntegrationReplay:

    def test_ra_start_time(self, channel):
        print(channel)

Если я передаю список в тест как приспособление, например:

    def test_ra_start_time(self, alist):
        for channel in alist:
            print(channel)

Работает хорошо, но не работает с переходом на @ pytest.mark.parametrize

Ответы

1 MrBeanBremen Dec 15 2020 at 00:01

Как упоминалось в комментарии, вы не можете напрямую передать фикстуру mark.parametrizeдекоратору, потому что декоратор оценивается во время загрузки.
Вместо этого вы можете выполнить параметризацию во время выполнения, реализовав pytest_generate_tests:

import pytest

@pytest.hookimpl
def pytest_generate_tests(metafunc):
    if "alist" in metafunc.fixturenames:
        values = metafunc.config.option.alist
        if value is not None:
            metafunc.parametrize("alist", value.split(","))

def test_ra_start_time(alist):
    for channel in alist:
        print(channel)

def test_something_else():
    # will not be parametrized
    pass

Параметризация выполняется на основании наличия alistпараметра в тестовой функции. Чтобы параметризация работала, этот параметр необходим (иначе вы получите ошибку из-за отсутствия аргумента).