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

У меня есть большой файл conftest.py, который я хочу разбить на более мелкие части по двум причинам:

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

Другие вопросы по тегам