Reputation: 4172
I need to add fixtures to the live_server
fixture provided by pytest-django
specifically an overwritten django_db_setup
.
That being said I understand it is not ideal to run tests against a db that isn't flushed clean but it is what I am working with.
In our normal test suite we use overwrite the django_db_setup
to do nothing in our conftest.py
file as follows
@pytest.fixture(scope="session")
def django_db_setup():
pass
It appears that when I use the live_server
fixture provided by pytest-django
it does not honor this as it attempts to flush the db at the end of the tests. How would one go about circumventing this? I've found an end around shown below but I'd like to avoid it if there is a better solution.
@pytest.fixture(scope='session')
def my_live_server(request):
request.getfixturevalue('django_db_setup')
return live_server(request)
Upvotes: 6
Views: 2278
Reputation: 4172
This is what I had to do to get around it. I am however getting a pytest warning for directly invoking the live_server
fixture. This can be avoided pytest<4
@pytest.fixture(scope="session")
def my_live_server(request):
request.getfixturevalue("fixture_i_want")
return live_server(request)
Upvotes: 0
Reputation: 66281
It appears that when I use the
live_server
fixture provided bypytest-django
it does not honor this as it attempts to flush the db at the end of the tests.
You're absolutely right; using the live-server
fixture in a test will silently trigger transactional behaviour (as if you would pass transactional_db
fixture to the test). AFAIK this can't be turned off via configuration (I will be glad if proven wrong); one has to mess with pytest-django
's internals. In your 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)
Sure, it's not a nice solution, but it does the trick. You can at least "mitigate the possible damage" by introducing a custom marker so that the patched helper is only applied to marked tests:
@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)
Now the new behaviour is applied only to tests marked with live_server_no_flush
:
@pytest.mark.live_server_no_flush
def test_spam(live_server):
...
Upvotes: 2