Python pytest django将装置添加到live_服务器装置

Python pytest django将装置添加到live_服务器装置,python,django,pytest,pytest-django,Python,Django,Pytest,Pytest Django,我需要将fixture添加到live_服务器fixture,fixture由pytest django提供,特别是被覆盖的django_db_设置 尽管如此,我理解对一个没有刷新干净的db运行测试并不理想,但这正是我正在使用的 在我们的普通测试套件中,我们使用覆盖django\u db\u设置在conftest.py文件中不执行任何操作,如下所示 @pytest.fixture(scope="session") def django_db_setup(): pass 当我使用pytes

我需要将fixture添加到
live_服务器
fixture,fixture由
pytest django
提供,特别是被覆盖的
django_db_设置

尽管如此,我理解对一个没有刷新干净的db运行测试并不理想,但这正是我正在使用的

在我们的普通测试套件中,我们使用覆盖
django\u db\u设置
conftest.py
文件中不执行任何操作,如下所示

@pytest.fixture(scope="session")
def django_db_setup():
    pass
当我使用
pytest-django
提供的
live_服务器
fixture时,它似乎不遵守这一点,因为它试图在测试结束时刷新数据库。人们将如何绕过这一点?我已经找到了一个终点,如下所示,但如果有更好的解决方案,我想避免它

@pytest.fixture(scope='session')
def my_live_server(request):
    request.getfixturevalue('django_db_setup')
    return live_server(request)
当我使用
pytest-django
提供的
live_服务器
fixture时,它似乎不遵守这一点,因为它试图在测试结束时刷新数据库

你完全正确;在测试中使用
live server
fixture将自动触发事务行为(就像您将
transactional\u db
fixture传递到测试中一样)。AFAIK这不能通过配置关闭(如果证明是错误的,我会很高兴);你必须搞乱pytest django的内部结构。在您的
conftest.py
中:

# conftest.py

import pytest

@pytest.fixture(scope="session")
def django_db_setup():
    pass

@pytest.fixture(autouse=True, scope='function')
def _live_server_helper(request):
    if 'live_server' not in request.funcargnames:
        return

    request.getfixturevalue('django_db_setup')

    live_server = request.getfixturevalue('live_server')
    live_server._live_server_modified_settings.enable()
    request.addfinalizer(live_server._live_server_modified_settings.disable)
当然,这不是一个好的解决方案,但它确实起到了作用。您至少可以通过引入自定义标记来“减轻可能的损害”,以便修补的辅助对象仅应用于标记的测试:

@pytest.fixture(autouse=True, scope='function')
def _live_server_helper(request):
    markers = [marker.name for marker in request.node.iter_markers()]
    if 'live_server_no_flush' not in markers:
        request.getfixturevalue('_live_server_helper')
        return

    # rest of code same as above
    if 'live_server' not in request.funcargnames:
        return

    request.getfixturevalue('django_db_setup')

    live_server = request.getfixturevalue('live_server')
    live_server._live_server_modified_settings.enable()
    request.addfinalizer(live_server._live_server_modified_settings.disable)
现在,新的行为仅适用于标有
live\u server\u no\u flush
的测试:

@pytest.mark.live_server_no_flush
def test_spam(live_server):
    ...

这就是我必须要做的,才能绕过它。但是,我因为直接调用
live_服务器
fixture而收到pytest警告。这是可以避免的Pytest是的,我最初只是将
live_server
定义复制到我们的代码库中,但并不特别喜欢这个解决方案,因为这意味着如果上游代码库发生任何更改,我们必须更新fixture。我希望有某种方式可以通过设置或其他方式“传递”固定装置。最后是一个简单的包装夹具。似乎是最简单的解决方案。也感谢您的编辑。@Adam您介意分享您使用的简单包装夹具吗?@libcthorne这基本上是我必须做的事情