Почему не загружается pytest conftest.py при выполнении только подмножества тестов?

#python #pytest

#python #pytest

Вопрос:

Вот мой макет каталога тестов API:

 api_tests
├── conftest.py
└── query
    └── me_test.py
  

Содержимое conftest.py:

 print("CONFTEST LOADED")
  

Содержимое me_test.py:

 """Tests the "me" query"""

def test_me():
    assert True
  

Если я просто запускаю pytest , все работает:

 ================================================= test session starts =================================================
platform linux -- Python 3.8.5, pytest-6.1.0, py-1.9.0, pluggy-0.13.1
rootdir: /home/hubro/myproject, configfile: pytest.ini
collecting ... CONFTEST LOADED
collected 3 items                                                                                                     

api_tests/query/me_test.py .                                                                                    [ 33%]
lib/myproject/utils_test.py .                                                                                   [ 66%]
lib/myproject/schema/types/scalars_test.py .                                                                    
  

Выводится сообщение «CONFTEST LOADED». Отлично! Однако этот тестовый запуск также собрал все мои модульные тесты, которые мне не нужны. Я хочу разделить свои тестовые прогоны на модульные тесты и тесты API, я не хочу запускать их все за один раз.

Однако, если я просто запускаю pytest api_tests/ :

 ================================================= test session starts =================================================
platform linux -- Python 3.8.5, pytest-6.1.0, py-1.9.0, pluggy-0.13.1
rootdir: /home/hubro/myproject, configfile: pytest.ini
collected 1 item                                                                                                      

api_tests/query/me_test.py .                                                                                    [100%]

================================================== 1 passed in 0.00s ==================================================
  

Теперь выполняются правильные тесты, но conftest.py файл не был загружен… Как так получилось?


Я использую Pytest 6.1.0 на Python 3.8.


РЕДАКТИРОВАТЬ: Хорошо, я нашел приемлемое решение. Я могу переопределить параметры INI-файла через командную строку с -o помощью опции. Это работает:

 poetry run pytest -o "testpaths=api_tests"
  

Тем не менее, я бы очень хотел получить ответ на исходный вопрос, поэтому я не собираюсь его удалять.

Комментарии:

1. Локальный conftest плагин будет загружен так или иначе. Разница только в коллекции, поэтому печать будет проглочена при втором вызове.

2. @hoefling О черт, ты прав… 🤦 Продолжайте и напишите это в ответе, и я отмечу его как правильный…

3. Не волнуйтесь, pytest поддержка вложенных тестов довольно сложна и имеет множество нежелательных побочных эффектов, это один из них.

Ответ №1:

conftest Плагин будет зарегистрирован в обоих вызовах, единственное отличие заключается в стадии регистрации. Если вы сомневаетесь, добавьте --traceconfig аргумент в список зарегистрированных плагинов в порядке их регистрации:

 $ pytest --traceconfig
PLUGIN registered: <_pytest.config.PytestPluginManager object at 0x7f23033ff100>
PLUGIN registered: <_pytest.config.Config object at 0x7f2302d184c0>
...
=================================== test session starts ===================================
...
PLUGIN registered: <module 'conftest' from 'path/to/conftest.py'>
...
  

При первом вызове файл conftest.py не будет найден сразу, поскольку он находится по корневому пути теста, поэтому он будет загружен во время pytest обнаружения тестов. Во втором вызове conftest.py находится в корне теста, поэтому он будет загружен еще до начала тестового сеанса (после загрузки плагинов, переданных через -p arg и зарегистрированных через setuptools entrypoint). Запуск pytest -s (с отключенным захватом выходных данных) должен показать пользовательскую печать, расположенную над ==== test session starts ==== строкой.

Если вы хотите, чтобы print был идентичным между двумя вызовами, поместите его в подходящий хук. Например, чтобы всегда печатать CONFTEST loaded после завершения сбора тестов, используйте:

 # api_tests/conftest.py

def pytest_collectreport(report):
    print("CONFTEST loaded")
  

Для пользовательского размещения выходных данных доступны и другие варианты; лучше всего проверить список доступных перехватов в pytest разделе Ссылки на перехваты.