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

У меня есть некоторые данные в a_file, с которыми мне нужно параметризовать мой прибор.Поэтому я написал вспомогательную функцию, которая возвращает a_list, заполненную данными из файла.Теперь я могу легко параметризовать свой прибор с помощью @pytest.fixture(params=a_list).Кажется прямо, не так ли?

Проблема здесь в том, что a_file генерируется другим прибором, и кажется, что pytest вызывает помощник, который полагается на этот файл, прежде чем файл действительно будет создан прибором.Из-за этого поведения FileNotFoundError повышается.

Мой код выглядит следующим образом:

def helper_returning_list_from_a_file():
    with open("a_file") as a_file:
        a_list = a_file.readlines()

    return a_list

@pytest.fixture(scope="session")
def create_file_fixture(depends_on_other_fixtures):
    # create "a_file" here

@pytest.fixture(params=helper_returning_list_from_a_file())
def a_fixture_which_is_parametrized_with_data_from_a_file(request):
    return request.param

def test_which_uses(a_fixture_which_is_parametrized_with_data_from_a_file):
    assert False

Добавление: create_file_fixture должен быть приспособлениеми не может быть преобразован в обычную функцию, потому что это зависит от других приборов.


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

Очевидное решение - убедиться, что файл создан доисполняется вспомогательная функция, которой нужен файл.

Поэтому я

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

    @pytest.fixture(params=helper_returning_list_from_a_file())
    def a_fixture_which_is_parametrized_with_data_from_a_file(create_file_fixture, request):
        return request.param
    
  • добавил флаг autouse в прибор, который создает файл следующим образом:

    @pytest.fixture(scope="session", autouse=True)
    def create_file_fixture:
        # create "a_file" here
    

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


Вопрос

Как я могу убедиться, что create_file_fixture выполняется первым?


Возможное решение

Я думаю, что возможным решением было бы также преобразование вспомогательной функции в прибор.Таким образом, я мог бы легко добавить зависимость, которая диктовала бы pytest, в каком порядке должны выполняться приборы.Это выглядело бы так:

@pytest.fixture()
def fixture_returning_list_from_a_file(create_file_fixture):
with open("a_file") as a_file:
    a_list = a_file.readlines()

return a_list

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

1 Ответ

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

Ошибка не вызвана pytest как таковой.Это вызвано тем, что ваша вспомогательная функция вызывается, когда модуль загружается интерпретатором Python, номинально до того, как он попадет в pytest.

К сожалению, вы не можете получить более одного значения из фиксатора,и вы не можете параметризоваться через ленивый генератор.Причина в том, что перед запуском любых приборов или тестов должен быть рассчитан полный график, что означает знание всех параметров заранее, как объяснено в этот неудавшийся запрос функции . @ Комментарий Хофлинга предлагает один из способов обойти это.Я хотел бы предложить способ, который, вероятно, является менее pytest-thonic, но все же должен работать.

Чтобы гарантировать, что ваш файл создан заранее и что весь список доступен для параметризации, не делайте егоfixture: просто запустите его как часть кода загрузки вашего модуля и сделайте список атрибутом модуля.Это не помешает вам использовать его в другом месте.Если несколько тестовых модулей используют один и тот же список, вы можете просто поместить его в отдельный не тестовый модуль и импортировать в те тесты, которые в нем нуждаются.

def create_file_function():
    # create "a_file" here
    return 'a_file'

def helper_returning_list_from_a_file():
    with open(create_file_function()) as a_file:
        a_list = a_file.readlines()

    return a_list

a_list = helper_returning_list_from_a_file()

@pytest.fixture(params=a_list)
def a_fixture_which_is_parametrized_with_data_from_a_file(request):
    return request.param

def test_which_uses(a_fixture_which_is_parametrized_with_data_from_a_file):
    assert False

Я думаю, что это немного более элегантно / настраиваетсяcreate_file_function возвращает имя файла.

Учитывая a_file, который выглядит следующим образом:

ABC
DEF

Вывод pytest -v выглядит следующим образом:

============================= test session starts ==============================
platform linux -- Python 3.6.4, pytest-3.4.2, py-1.5.2, pluggy-0.6.0 -- /...
cachedir: .pytest_cache
rootdir: /..., inifile:
plugins: remotedata-0.2.0, pep8-1.0.6, openfiles-0.2.0, doctestplus-0.1.2, arraydiff-0.2
collected 2 items                                                              

52765085.py::test_which_uses[ABC\n] PASSED                                [ 50%]
52765085.py::test_which_uses[DEF] PASSED                                  [100%]

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