Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytest-django won't allow database access even with mark

I'm having a difficult time figuring out what is wrong with my setup. I'm trying to test a login view, and no matter what I try, I keep getting:

Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.

My test:

import pytest

from ..models import User


@pytest.mark.django_db
def test_login(client):
    # If an anonymous user accesses the login page:
    response = client.get('/users/login/')
    # Then the server should respond with a successful status code:
    assert response.status_code == 200

    # Given an existing user:
    user = User.objects.get(username='user')
    # If we attempt to log into the login page:
    response = client.post('/users/login/', {'username': user.username, 'password': 'somepass'})
    # Then the server should redirect the user to the default redirect location:
    assert response.status_code == 302

My conftest.py file, in the same tests directory:

import pytest

from django.core.management import call_command


@pytest.fixture(autouse=True)
def django_db_setup(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        call_command('loaddata', 'test_users.json')

My pytest.ini file (which specifies the correct Django settings file):

[pytest]
DJANGO_SETTINGS_MODULE = config.settings

I'm stumped. I've tried using scope="session" like in the documentation together with either an @pytest.mark.django_db mark, a db fixture (as a parameter to the test function), or both with no luck. I've commented out each line of the test to figure out which one was triggering the problem, but couldn't figure it out. I could only get the test to run at all if I removed all db-dependent fixtures/marks/code from the test and had a simple assert True. I don't believe the issue is in my Django settings, as the development server runs fine and is able to access the database.

What am I missing here?

like image 999
Adam Avatar asked May 31 '19 05:05

Adam


2 Answers

Apparently this is a case of "deceiving exception syndrome". I had a migration that created groups with permissions, and since tests run all migrations at once, the post-migrate signal that creates the permissions that migration depends on was never run before getting to that migration.

It seems that if there is any database-related error before the actual tests start running, this exception is raised, which makes it very difficult to debug exactly what is going wrong. I ended up updating my migration script to manually cause permissions to be created so that the migration could run, and the error went away.

like image 58
Adam Avatar answered Sep 25 '22 12:09

Adam


You can add below code in your conftest.py as per the official documentation to allow DB access without django_db marker.

@pytest.fixture(autouse=True)
def enable_db_access_for_all_tests(db):
    pass

Ref: https://pytest-django.readthedocs.io/en/latest/faq.html#how-can-i-give-database-access-to-all-my-tests-without-the-django-db-marker

like image 33
Pyae Hlian Moe Avatar answered Sep 22 '22 12:09

Pyae Hlian Moe