如何覆盖在 pytest 4 中调用原始的 pytest fixture
How to override a pytest fixture calling the original in pytest 4
我正在定义一个覆盖 the django_db_setup
fixture.
的 pytest 装置
为了安全起见,我所做的更改设置了额外的拆解,因为有使用此固定装置的集成测试,它可能会产生进程,并且有时需要进行清理以防止所有东西损坏。
这似乎是合理的,并且在 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 中处理这种情况的推荐方法是什么?我们是否鼓励从我们想要覆盖的固定装置中复制粘贴代码,或者是否有另一种方法 "inherit" 固定装置,并在 之前和之后 注入例如自定义行为叫什么?
有一个简单的技巧可以使用自定义实现重新定义夹具。只需在本地测试代码中声明一个具有相同名称和签名的夹具(我通常在项目根目录的 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
参数 - 这确保在自定义夹具之前调用原始夹具。
"Redeclaration"
如果省略参数,自定义夹具将替换原来的夹具,因此不会执行:
@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'
))
顺便说一句,这是另一个方便的技巧。想要关闭在别处定义的灯具。
要在调用初始夹具之前注入自定义行为,您可以使用此行为创建单独的夹具,并在夹具的参数列表中的初始夹具之前使用它来覆盖先前定义的:
@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')
我正在定义一个覆盖 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 中处理这种情况的推荐方法是什么?我们是否鼓励从我们想要覆盖的固定装置中复制粘贴代码,或者是否有另一种方法 "inherit" 固定装置,并在 之前和之后 注入例如自定义行为叫什么?
有一个简单的技巧可以使用自定义实现重新定义夹具。只需在本地测试代码中声明一个具有相同名称和签名的夹具(我通常在项目根目录的 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
参数 - 这确保在自定义夹具之前调用原始夹具。
"Redeclaration"
如果省略参数,自定义夹具将替换原来的夹具,因此不会执行:
@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'
))
顺便说一句,这是另一个方便的技巧。想要关闭在别处定义的灯具。
要在调用初始夹具之前注入自定义行为,您可以使用此行为创建单独的夹具,并在夹具的参数列表中的初始夹具之前使用它来覆盖先前定义的:
@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')