简体   繁体   中英

Pytest django database access not allowed with django_db mark

I'm using pytest and I have problem with database access in fixture below. I have django_db mark everywhere.

[test_helpers.py]
import pytest
from django.test import Client
from weblab.middleware.localusermiddleware import _set_current_user

@pytest.fixture(scope="class")
@pytest.mark.django_db
def class_test_set_up(request):
    request.cls.client = Client()
    username = "username"
    user = User.objects.get(username=username)
    _set_current_user(user)

I'm getting RuntimeError: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it. In line user = User.objects.get(username=username)

[test_tmp_fixture.py]
import pytest
from tests.factories.sample.test_factories import TestFactory
from tests.tests_helpers.test_helpers import class_test_set_up

SIZE = 5

@pytest.mark.django_db
@pytest.fixture(scope="class")
def set_up_objs(request):
    request.cls.factory = TestFactory
    request.instance.objs = request.cls.factory.create_batch(SIZE)

@pytest.mark.django_db
@pytest.mark.usefixtures("class_test_set_up", "set_up_objs")
class TestTest:
    @pytest.mark.django_db
    def test_test(self):
        print("Hello Pytest")

My setup is pytest-7.0.1 with plugins: lazy-fixture-0.6.3, Faker-13.3.2, django-4.5.2 and django version 3.2.12

In traceback console shows problems with /pytest_lazyfixture.py:39:

According to the pytest-django documentation , django_db mark may not help if you need access to the Django database inside a fixture ( class_test_set_up in your case):

在此处输入图像描述

In your specific use-case, you are trying to access the django DB within a class scoped fixture. From what I've been able to look up, it seems that django doesn't support that.

To fix your issue, as the note in the documentation suggests, your fixture should explicitly request the db fixture and the class scope should be removed:

@pytest.fixture
def class_test_set_up(request, db):
    if not hasattr(request.cls, 'client'):
        request.cls.client = Client()
        username = "username"
        user = User.objects.get(username=username)
        _set_current_user(user)

Note - I would consider using the client fixture from pytest-django instead of implementing the fixture above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM