Pytest-django: Doctest intermittently getting "Failed: Database access not allowed, use the "django_db" mark to enable"

Created on 22 Dec 2015  路  6Comments  路  Source: pytest-dev/pytest-django

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.

documentation enhancement

Most helpful comment

@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

All 6 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clintonb picture clintonb  路  4Comments

koxu1996 picture koxu1996  路  3Comments

mjk4 picture mjk4  路  4Comments

mpasternak picture mpasternak  路  5Comments

aljosa picture aljosa  路  8Comments