如何覆盖在 pytest 4 中调用原始文件的 pytest 固定装置

tut*_*uju 5 python fixtures pytest pytest-django

我定义一个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.
Run Code Online (Sandbox Code Playgroud)

在 pytest 4 中处理这种情况的推荐方法是什么?我们是否鼓励从我们想要覆盖的装置中复制粘贴代码,或者是否有另一种方法来“继承”一个装置,并调用之前和之后注入例如自定义行为?

san*_*ash 12

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

@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')
Run Code Online (Sandbox Code Playgroud)


hoe*_*ing 7

有一个简单的技巧可以使用自定义实现重新定义固定装置。只需在本地测试代码中声明一个具有相同名称和签名的固定装置(我通常在项目根目录中进行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')
Run Code Online (Sandbox Code Playgroud)

请注意,我在自定义固定装置中有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'
    ))
Run Code Online (Sandbox Code Playgroud)

顺便说一句,当您想要关闭其他地方定义的灯具时,这是另一个方便使用的技巧。