Я построил серию тестов (с использованием pytest) для кодовой базы, взаимодействующей с Github API (как для выполнения вызовов, так и для получения веб-перехватчиков).
В настоящее время эти тесты работают с полуреалистичной имитацией github: вызовы github перехватываются через Ответы Часового и выполняются с помощью поддельной реализации github / git (нужных мне битов), с которой также можно взаимодействовать непосредственно из тестовых случаев. Любой веб-перехватчик, который необходимо активировать, использует Тестовый клиент Werkzeug для обратного вызова в приложение WSGI, используемое в качестве конечной точки веб-перехватчика.
Это работает хорошо, быстро (достаточно) и является отличным вариантом по умолчанию, но я хотел бы иметь возможность запускать те же тесты против самого github, и именно здесь я в тупике: мне нужно отключить текущие реализации систем под test (прямой «библиотечный» доступ к кодовой базе и фиктивный github) с разными (API-доступ к «внешней» кодовой базе и фактическому github), и я не совсем уверен, как действовать дальше.
Я попытался использовать pytest_generate_tests, чтобы отключить реализации приспособлений (кодовой базы и github) через плагин, но я не совсем знаю, сработает ли это вообще, и пока мои попытки загрузить локальный файл как плагин в pytest через pytest -p <package_name> не имели большого успеха.
Я хотел бы знать, иду ли я в правильном направлении, и в этом случае может ли кто-нибудь помочь с использованием «локальных» плагинов (не устанавливаемых через setuptools и не основанных на conftest.py) в pytest.
Не уверен, что это имеет какое-то отношение, но я использую pytest 3.6.0, работающий на CPython 3.6, запросы 2.18.4, ответы 0.9.0 и Werkzeug 0.14.1.






Есть несколько способов подойти к этому. Тот, который я бы выбрал по умолчанию, запускает ваши фиктивные тесты, а затем, когда присутствует флаг командной строки, тестирует оба, макет и настоящую версию.
Итак, сначала более простая часть, добавив параметр командной строки:
def pytest_addoption(parser):
parser.addoption('--github', action='store_true',
help='Also test against real github')
Теперь это доступно через приспособление pytestconfig как pytestconfig.getoption('github'), часто также доступно косвенно, например. через приспособление запросов как request.config.getoption('github').
Теперь вам нужно использовать эту параметризацию любого теста, который должен взаимодействовать с API github, чтобы они запускались как с макетом, так и с реальным экземпляром. Не зная вашего кода, похоже, что хорошей точкой будет клиент Werkzeug: превратите его в приспособление, а затем его можно параметризовать для возврата как реального клиента, так и тестового клиента, о котором вы упоминаете:
@pytest.fixture
def werkzeug_client(werkzeug_client_type):
if werkzeug_client_type == 'real':
return create_the_real_client()
else:
return create_the_mock_client()
def pytest_generate_tests(metafunc):
if 'werkzeug_client_type' in metafunc.fixturenames:
types = ['mock']
if metafunc.config.getoption('github'):
types.append('real')
metafunc.parametrize('werkzeug_client_type', types)
Теперь, если вы напишете свой тест как:
def test_foo(werkzeug_client):
assert werkzeug_client.whatever()
При запуске с pytest --github вы получите один тест в обычном режиме и два теста.
(Имейте в виду, что хуки должны быть в файлах conftest.py, в то время как фикстуры могут быть где угодно. Имейте в виду, что ловушка pytest_addoption действительно должна использоваться только в файле conftest верхнего уровня, чтобы избежать путаницы в том, когда ловушка используется pytest, а когда нет. Итак вы действительно должны поместить весь этот код в файл conftest.py верхнего уровня.)
Принятие этого ответа, потому что он отвечает на вопрос о направлении (с уверенностью, что он правильный), и он может быть полезен для других посетителей. Мой набор приспособлений слишком сложен для такого тривиального условного обозначения, но через некоторое время на pytest IRC и помощи Ронни Пфанншмидта (я думаю) мне удалось настроить «эксклюзивные плагины», так что локальная / фиктивная реализация различных приспособлений используется по умолчанию, но я могу вызвать pytest с помощью -p remote_plugin, чтобы не загружать фиктивные фикстуры и вместо этого загружать «настоящие» фикстуры.
Вы можете создать параметризованное приспособление, который возвращает различные реализации серверной части. После внедрения в тест он создаст разные экземпляры одного и того же теста, которые будут выполняться с разными бэкэндами. Если это не то, что вам нужно, рассмотрите возможность создания mcve.