pytest-django
pytest-django copied to clipboard
Doctest intermittently getting "Failed: Database access not allowed, use the "django_db" mark to enable"
Using Python 3.4, pytest-django 2.8.0, pytest 2.7.0, django 1.7.6, & Postgresql 9.3.9
When running my unit tests I have an intermittent error returning from my one and only Doctest. All my unit tests pass just fine and many use the database. Here's my test invocation: time py.test -n 7 -s -v --durations=10
273 Goals must be created within the context of a Portfolio. 274 >>> import pytest 275 >>> pytestmark = pytest.mark.django_db() 276 >>> from portfolio.models import Portfolio 277 >>> p, new = Portfolio.objects.get_or_create(name="Sample Goals") UNEXPECTED EXCEPTION: Database access not allowed, use the "django_db" mark to enable
Removing lines 274 & 275 have no impact.
Sorry, doctests and pytest fixtures (which is used to get the database ready for use) does not really play well together. The error message is misleading, but doing database operations within a doctest is not supported by pytest-django.
doctests called from Django's test runner never cleaned up the database AFAIK, and starting from Django 1.6, Django's own test runner does not automatically run doctests, therefore it is not something that is likely to be directly supported by pytest-django, either.
I think your best bet is to rewrite your single doctest to an ordinary test case.
@scherrey
i have found the following fixture allows db access in my doctests
@pytest.fixture
def db_doctest(request, _django_cursor_wrapper):
from django.test import TestCase as django_case
_django_cursor_wrapper.enable()
request.addfinalizer(_django_cursor_wrapper.disable)
case = django_case(methodName='__init__')
case._pre_setup()
request.addfinalizer(case._post_teardown)
@pelme i would be happy to create a PR if its useful to. I find doctests can be very useful as a form of testable documentation, as opposed to a replacement for unit testing
@phlax Yes, I think it would be good to have, but should be covered by tests, of course. Thanks for digging into this and suggesting a fix!
@phlax How do you use this fixture? I mean, what code goes where in the doctest file?
@alanjds sorry it took 3 years to answer 8/ - just noticed the question when i was re-discovering the solution.
You can include fixtures in doctests with eg
>>> get_fixture('db_doctest')
but the above solution has also changed - this seems to be enough for the doctest fixture:
import pytest
@pytest.fixture
def db_doctest(db):
pass
As of July 2020, getfixture('db') at the top of your doctest works.