Разбиение файла conftest.py на несколько меньших частей, похожих на conftest
У меня есть большой файл conftest.py, который я хочу разбить на более мелкие части по двум причинам:
- Файл очень большой (~1000 строк, включая документацию)
- Некоторые из приборов зависят от других приборов, и у меня нет причин выставлять эти другие приборы как часть "API" контеста, когда пользователи ищут соответствующие приборы.
Я не знаю ни одного механизма, предоставленного pytest для разрешения конфликтных файлов в нескольких местах в одной папке, поэтому я придумал один ниже:
import sys
import os
sys.path.append(os.path.dirname(__file__))
from _conftest_private_part_1 import *
from _conftest_private_part_2 import *
from _conftest_private_part_3 import *
@pytest.fixture
def a_fixture_that_is_part_of_the_public_conftest_api():
pass
Это работает для моих нужд, но мне интересно, есть ли лучший способ.
3 ответа
Вы можете поместить свои вещи в другие модули и ссылаться на них, используя pytest_plugins
переменная в вашем conftest.py
:
pytest_plugins = ['module1', 'module2']
Это также будет работать, если ваш conftest.py
имеет крючки на них.
Тебе не нужна какая-то необычная магия для этого. py.test автоматически добавляет путь к текущему тестовому файлу в sys.path
, а также все родительские пути до каталога, на который он был нацелен.
Из-за этого вам даже не нужно помещать этот общий код в conftest.py
, Вы можете просто поместить в простые модули или пакеты и затем импортировать их (если вы хотите поделиться приборами, они должны быть в conftest.py
).
Также есть примечание об импорте из conftest.py
в документации:
Если у вас есть файлы conftest.py, которые не находятся в каталоге пакета python (то есть, содержащем
__init__.py
) затем "import conftest
Может быть неоднозначным, потому что могут быть другиеconftest.py
файлы, а также на вашемPYTHONPATH
или жеsys.path
, Таким образом, это хорошая практика для проектовconftest.py
в рамках пакета или никогда не импортировать что-либо изconftest.py
файл.
В качестве альтернативы вы можете попробовать:
В
my_fixtures.py
:
@pytest.fixture
def some_fixture():
yield
В
conftest.py
:
import my_fixtures
# Adding the fixture to attributes of `conftest` will register it
some_fixture = my_fixtures.some_fixture
Кажется, что
pytest
обнаружить приспособление, перебирая
conftest
атрибуты и проверка некоторых
attr._pytestfixturefunction
Добавлено
@pytest.fixture
.
Так что пока
conftest.py
содержит атрибуты фикстуры, на самом деле не имеет значения, какой файл определен фикстурой:
Это работает для меня и кажется проще / понятнее:
Тесты верхнего уровня /conftest.py (пример многоразовой отладки при печати запросов. Ответ):
import pytest
import requests
from requests_toolbelt.utils import dump
@pytest.fixture(scope="session")
def print_response(response: requests.Response):
data = dump.dump_all(response)
print("========================")
print(data.decode('utf-8'))
print("========================")
print("response.url = {}".format(response.url))
print("response.request = {}".format(response.request))
print("response.status_code = {}".format(response.status_code))
print("response.headers['content-type'] = {}".format(response.headers['content-type']))
print("response.encoding = {}".format(response.encoding))
try:
print("response.json = {}".format(response.json()))
except Exception:
print("response.text = {}".format(response.text))
print("response.end")
Из низкоуровневого контеста импортируйте код более высокого уровня - например, tests/package1/conftest.py:
from tests.conftest import *
Затем в ваших тестах нижнего уровня в tests/package1/test_*. Py вы просто импортируете через:
from tests.package1 import conftest
И тогда у вас есть объединенные конфигурационные тесты из одного доступного. Повторите этот шаблон для других подробных / модульных файлов conftest.py более низкого уровня по всей иерархии тестов.