Как переопределить прибор Pytest, вызывающий оригинал в Pytest 4 - PullRequest
2 голосов
/ 16 мая 2019

Я определяю прибор Pytest, который переопределяет прибор django_db_setup .

Имеющееся у меня изменение устанавливает дополнительные ограничения для обеспечения безопасности, поскольку существуют интеграционные тесты, в которых используется этот прибор, который может порождать процессы, и иногда требуется очистка, чтобы не допустить поломки всех элементов.

Это кажется разумным и также предлагается в документах Pytest. Однако я не хочу копировать и вставлять ту же самую логику django_db_setup, так как я доволен тем, что уже есть. Однако запуск его как функции вызывает предупреждение об устаревании:

/usr/local/lib/python3.6/dist-packages/_pytest/fixtures.py:799:

 RemovedInPytest4Warning: Fixture "django_db_setup" called directly.
 Fixtures are not meant to be called directly, are created automatically
 when test functions request them as parameters. See
 https://docs.pytest.org/en/latest/fixture.html for more information.

Каков рекомендуемый способ решения этой ситуации в pytest 4? Рекомендуется ли копировать и вставлять код из приборов, которые мы хотим переопределить, или есть другой способ «наследовать» прибор и внедрять, например, пользовательское поведение до, а также после , когда оно вызывается?

Ответы [ 2 ]

2 голосов
/ 17 мая 2019

Чтобы внедрить пользовательское поведение перед вызовом исходного прибора, вы можете создать отдельный прибор с этим поведением и использовать его перед начальным прибором в списке параметров прибора, который переопределяет ранее определенное:

@pytest.fixture(scope='session')
def inject_before():
    print('inject_before')

@pytest.fixture(scope='session')
def django_db_setup(inject_before, django_db_setup):
    print('inject_after')
1 голос
/ 16 мая 2019

Существует простой трюк для переопределения прибора с пользовательским импл. Просто объявите прибор с тем же именем и подписью в вашем локальном тестовом коде (я обычно делаю это в conftest.py в корне проекта). Примеры:

"Inheritance"

# conftest.py

import pytest


@pytest.fixture(scope='session')
def django_db_setup(
    request,
    django_db_setup,
    django_test_environment,
    django_db_blocker,
    django_db_use_migrations,
    django_db_keepdb,
    django_db_createdb,
    django_db_modify_db_settings,
):
    # do custom stuff here
    print('my custom django_db_setup executing')

Обратите внимание, у меня есть аргумент django_db_setup в пользовательском устройстве django_db_setup - это гарантирует, что исходный прибор вызывается раньше, чем пользовательский.

"переопределение"

Если вы пропустите аргумент, пользовательский прибор заменит исходный, поэтому он не будет выполнен:

@pytest.fixture(scope='session')
def django_db_setup(
    request,
    django_test_environment,
    django_db_blocker,
    django_db_use_migrations,
    django_db_keepdb,
    django_db_createdb,
    django_db_modify_db_settings,
):
    print((
        'my custom django_db_setup executing - '
        'original django_db_setup will not run at all'
    ))

Кстати, это еще один удобный прием, когда вы, например, хочу отключить прибор, который определен в другом месте.

...