You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pytest-django标记django_db仍提示Database access not allowed报错

问题原因
  • @pytest.mark.django_db标记仅对测试类、测试方法生效,装饰在fixture上不会开启数据库访问权限,属于无效写法。
  • 定义的两个fixture都是class级别作用域,pytest-django默认提供的db/transactional_dbfixture是function级别,无法直接注入到更高作用域的fixture中完成权限开启。
  • 安装的pytest-lazy-fixture 0.6.3版本与当前使用的pytest 7.0.1、pytest-django 4.5.2存在兼容性bug,会错误拦截数据库访问校验,错误回溯指向pytest_lazyfixture.py:39就是该问题导致。
  • 原代码中class_test_set_upfixture缺少User模型的导入,也会触发执行错误。
解决方案
  1. 移除所有fixture上的@pytest.mark.django_db装饰器,该装饰器对fixture无效。

  2. 处理插件兼容性问题:

    • 若项目中未使用lazy fixture能力,直接卸载pytest-lazy-fixture包即可;
    • 若需要使用该插件,将其升级到0.6.5及以上兼容pytest 7.x的版本。
  3. 针对class级别fixture的数据库访问需求,使用pytest-django提供的django_db_blocker内置fixture手动解锁数据库权限,修正后的参考代码如下:

    修正后的test_helpers.py代码:

    import pytest
    from django.test import Client
    from django.contrib.auth.models import User
    from weblab.middleware.localusermiddleware import _set_current_user
    
    @pytest.fixture(scope="class")
    def class_test_set_up(request, django_db_blocker):
        with django_db_blocker.unblock():
            request.cls.client = Client()
            username = "username"
            user = User.objects.get(username=username)
            _set_current_user(user)
    

    修正后的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.fixture(scope="class")
    def set_up_objs(request, django_db_blocker):
        with django_db_blocker.unblock():
            request.cls.factory = TestFactory
            request.cls.objs = request.cls.factory.create_batch(SIZE)
    
    @pytest.mark.django_db
    @pytest.mark.usefixtures("class_test_set_up", "set_up_objs")
    class TestTest:
        def test_test(self):
            print("Hello Pytest")
    
注意事项

使用django_db_blocker.unblock()解锁class级别fixture的数据库权限时,fixture中操作产生的数据不会在单个测试方法执行后自动回滚,会在整个测试类的所有用例执行完成后才清理。如果需要测试方法之间的数据隔离,将fixture作用域调整为默认的function级别,同时显式注入dbfixture即可,无需手动调用unblock:

@pytest.fixture(scope="function")
def class_test_set_up(request, db):
    request.cls.client = Client()
    username = "username"
    user = User.objects.get(username=username)
    _set_current_user(user)

内容的提问来源于stack exchange,提问作者user3565923

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 08:03:22