Разделение файла conftest.py на несколько более мелких частей, похожих на conftest
Я столкнулся с проблемой разделения большого файла conftest.py
, который содержит ~1000 строк, включая документацию. Основные причины, по которым я хочу его разбить на более мелкие части, следующие:
- Файл слишком большой, и его сложно поддерживать и читать.
- Некоторые фикстуры зависят от других фикстур, и нет необходимости экспонировать эти зависимые фикстуры как часть "API" conftest, когда пользователи ищут релевантные фикстуры.
Я не знаю о каких-либо механизмах, предоставляемых pytest
, которые позволяли бы использовать несколько файлов conftest.py
в разных частях одной и той же папки, поэтому я придумал следующее решение:
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
Это решение работает для моих нужд, но мне интересно, есть ли более лучший способ структурирования conftest.py
. Кто-то сталкивался с подобной проблемой?
2 ответ(ов)
В ответ на ваш вопрос, вы можете попробовать следующий подход:
В файле my_fixtures.py
:
@pytest.fixture
def some_fixture():
yield
В файле conftest.py
:
import my_fixtures
# Добавление фикстуры в атрибуты `conftest` зарегистрирует её
some_fixture = my_fixtures.some_fixture
Судя по всему, pytest
обнаруживает фикстуры, перебирая атрибуты conftest
и проверяя наличие атрибута attr._pytestfixturefunction
, добавленного с помощью @pytest.fixture
.
Поэтому, пока в conftest.py
будут присутствовать атрибуты фикстур, не имеет значения, в каком файле фикстура определена.
Я сам этого не пробовал, но ожидаю, что следующее тоже должно сработать:
# В `conftest.py`
from my_fixtures import *
Этот способ может работать, так как он импортирует все фикстуры из файла my_fixtures.py
в ваш файл conftest.py
.
Это решение работает для меня и кажется проще/понятнее:
На верхнем уровне создайте файл tests/conftest.py
(пример повторно используемого вывода отладочной информации для объекта requests.Response
):
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")
Затем в файле conftest.py
более низкого уровня, например, tests/package1/conftest.py
, импортируйте код из верхнего уровня:
from tests.conftest import *
После этого в ваших тестах более низкого уровня внутри tests/package1/test_*.py
вы просто импортируете так:
from tests.package1 import conftest
Таким образом, у вас будет доступна объединенная конфигурация conftest
из одного файла. Повторите этот шаблон для других файлов conftest.py
более низкого уровня в иерархии тестов.
Как правильно проверить, что исключение возникает в pytest?
Как вывести стандартный вывод print() в консоль во время выполнения pytest?
Укажите, какие тесты pytest запускать из файла
Что такое conftest.py в Pytest?
Работают ли параметризованные тесты pytest с тестами на основе классов unittest?