Pytest: Как параметризовать тест со списком, который возвращается из прибора? - PullRequest
0 голосов
/ 11 октября 2018

Я хочу параметризовать тест со списком, который динамически создается с помощью прибора следующим образом:

@pytest.fixture
def my_list_returning_fixture(depends_on_other_fixtures):
    return ["a dynamically created list which", depends_on_other_fixtures]

Как мне этого добиться?В качестве альтернативы, как я могу гарантировать, что определенный прибор будет вызываться первым - это решит эту проблему еще до того, как она произойдет.


То, что я уже пробовал

  • Я попытался параметризовать тест с помощью прибора (который просто приводит к ошибкам, потому что python считает, что я хочу передать саму функцию):

    @pytest.mark.parametrize(
        "an_element_from_the_list_of_my_fixture", 
        my_list_returning_fixture
    )
    def test_the_list(an_element_from_the_list_of_my_fixture):
        print(an_element_from_the_list_of_my_fixture)
    

    Вызов прибора как обычная функция, напримерmy_list_returning_fixture() тоже приводит к ошибкам!Python не знает, как заполнить «параметры» прибора (которые на самом деле являются просто другими приборами) и отображает сообщение об ошибке о слишком малом количестве переданных аргументов ...

    Поэтому мне нужен pytest для внедрения depends_on_other_fixtures зависимостей, поэтому я не могу назвать ее как обычную функцию.

  • Я также попытался вставить другое устройство между устройством списка и тестом так:

    @pytest.fixture(params=my_list_returning_fixture)
    def my_interposed_parametrized_fixture(request):
        return request.param
    
    def test_the_list(my_interposed_parametrized_fixture):
        ...
    
  • Я также пытался поиграть с косвенной параметризацией, но она тоже не сработала ...


Это просто с помощью статических списков

Я знаю, что можно легко параметризовать тест с заданным list следующим образом:

the_list = [1, 2, 3]
@pytest.mark.parametrize("an_element_from_the_list", the_list)
def test_the_list(an_element_from_the_list):
    print(an_element_from_the_list)

Это приведет к трем тестам.По одному на каждый элемент в списке.

Ответы [ 2 ]

0 голосов
/ 03 июля 2019

Кажется, что это дубликат этого вопроса .

По замыслу это невозможно: концепция «фикстур» зарезервирована для выполнения теста, а концепция «Параметры "зарезервировано для проверки коллекции.Пожалуйста, смотрите мой подробный ответ здесь .

0 голосов
/ 11 октября 2018

Короткий ответ: вы не можете делать это так, как хотите, то есть с помощью приборов: https://github.com/pytest-dev/pytest/issues/2155. В основном, число вещей, которые были получены или возвращены, должно быть известно заранее, чтобы Pytest правильно вычислилграфик зависимостей фикстуры и теста.

Похоже, что единственный способ - это исправить элементы списка перед передачей их любому из декораторов pytests.Вот пример, связанный с вашим другим вопросом, показывающий, что проблема не может быть решена, скажем, генератором:

import pytest

def gen_lines():
    with open('file_that_does_not_exist') as f:
        yield from f

@pytest.fixture(scope='session')
def create_file():
    with open('file_that_does_not_exist', 'w') as f:
        print('ABC', file=f)
        print('DEF', file=f)

@pytest.fixture(params=gen_lines())
def line_fixture(request):
    return request.param

def test_line(line_fixture):
    assert True

Это не удастся во время сбора, когда pytest превращает ваш генератор в список.Добавление зависимости к line_fixture на create_file не поможет ни по той же причине.

На данный момент ваш единственный реальный вариант - запустить create_file во время загрузки модуля или раньше.

import pytest

def gen_lines():
    with open('file_that_does_not_exist') as f:
        yield from f

def create_file():
    with open('file_that_does_not_exist', 'w') as f:
        print('ABC', file=f)
        print('DEF', file=f)

create_file()

@pytest.fixture(params=gen_lines())
def line_fixture(request):
    return request.param

def test_line(line_fixture):
    assert True

Список не обязательно должен быть статическим сам по себе.Это просто не может быть создано приспособлением.Но не позволяй этому остановить тебя.Вы можете поместить код для определения и запуска create_file в отдельный модуль и просто импортировать его, где вам нужно, в качестве утилиты.Это затмит все беспорядочные детали и сделает ваш код таким же чистым, как и в случае с приборами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...