如何重写在pytest 4中调用原始的pytest固定装置

时间:2019-05-16 08:01:20

标签: python pytest fixtures pytest-django

我正在定义一个pytest固定装置,以覆盖the django_db_setup fixture

为安全起见,我进行了此项更改,因为有一些集成测试使用此夹具,这可能会产生进程,有时还需要进行清理以防止所有事物崩溃。

这似乎是合理的,并且在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 个答案:

答案 0 :(得分:1)

有一个简单的技巧可以使用自定义的impl重新定义灯具。只需在本地测试代码中声明具有相同名称和签名的灯具(我通常在项目根目录的conftest.py中声明)。例子:

“继承”

# 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'
    ))

顺便说一句,这是在您例如想关闭其他地方定义的灯具。

答案 1 :(得分:1)

要在调用初始固定装置之前注入自定义行为,您可以使用此行为创建单独的固定装置,并在覆盖先前定义的固定装置参数列表中的初始固定装置之前使用它:

@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')