0

Разделение файла conftest.py на несколько более мелких частей, похожих на conftest

4

Я столкнулся с проблемой разделения большого файла conftest.py, который содержит ~1000 строк, включая документацию. Основные причины, по которым я хочу его разбить на более мелкие части, следующие:

  1. Файл слишком большой, и его сложно поддерживать и читать.
  2. Некоторые фикстуры зависят от других фикстур, и нет необходимости экспонировать эти зависимые фикстуры как часть "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 ответ(ов)

0

В ответ на ваш вопрос, вы можете попробовать следующий подход:

В файле 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.

0

Это решение работает для меня и кажется проще/понятнее:

На верхнем уровне создайте файл 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 более низкого уровня в иерархии тестов.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь