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

使用django-pytest测试服务时出现User.DoesNotExist错误求助

问题排查:pytest测试Django服务时出现User.DoesNotExist错误及"No tables found"提示

问题现象

  • 运行pytest测试时,控制台能看到migrate输出,且生成了db_test.sqlite3测试数据库,但同时提示No tables found
  • 测试用例authentication/tests/test_services.py::test_register_user抛出错误:users.models.User.DoesNotExist: User matching query does not exist

相关代码与配置

conftest.py内容

import os

import pytest

from django.core.management import call_command
from rest_framework.test import APIClient

from users.models import User


@pytest.fixture(scope='session')
def delete_db():
    print("delete_db")
    try:
        os.remove("db_test.sqlite3")
    except Exception:
        pass


@pytest.fixture(scope='session')
def django_db_setup(delete_db, django_db_blocker):
    print("django_db_setup")
    with django_db_blocker.unblock():
        call_command('sqlflush')
    with django_db_blocker.unblock():
        call_command('migrate', '--noinput')
    yield


@pytest.fixture(autouse=True, scope='session')
def user(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        user = User.objects.create(
            name='Test user',
            email='test@eaxmple.com',
            password='Password'
        )


@pytest.fixture(autouse=True, scope='session')
def guest_client():
    return APIClient()


@pytest.fixture(autouse=True, scope='session')
def user_client(guest_client, django_db_blocker):
    with django_db_blocker.unblock():
        client = APIClient()
        user = User.objects.get(email='test@example.com')
        response = guest_client.post('/api/v1/auth/login/', data={"email": user.email, "password": "Adminqwe1,"})
        token = str(response.json().get("access"))
        client.credentials(HTTP_AUTHORIZATION="Bearer " + token)
        return client

测试用例文件(authentication/tests/test_services.py)

import pytest

from authentication.services import register_user


@pytest.mark.django_db()
def test_register_user(guest_client):
    data = {'email': 'test1@example.com', 'name': 'Test user', 'password': 'Adminqwe1.'}
    user = register_user(data=data)
    assert user.name == 'Test user'
    assert user.check_password('Admninqwe1.') is True

被测试函数(authentication/services.py)

from users.models import User


def register_user(data):
    password = data.pop("password")
    user = User.objects.create(**data)
    user.set_password(password)
    user.save()
    return user

settings_test.py数据库配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db_test.sqlite3',
    }
}

pytest.ini配置

[pytest]
DJANGO_SETTINGS_MODULE = config.settings_test

核心问题排查与修复

1. 邮箱拼写错误导致用户查找失败

user fixture中创建用户时,邮箱写成了test@eaxmple.com(多了一个x),但user_client fixture中查找用户用的是test@example.com,直接导致找不到用户抛出异常。

修复:
修正user fixture中的邮箱拼写:

@pytest.fixture(autouse=True, scope='session')
def user(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        user = User.objects.create(
            name='Test user',
            email='test@example.com',  # 修正拼写错误
            password='Password'
        )

2. django_db_setup冗余操作干扰表创建

sqlflush命令会清空数据库,但在删除旧数据库后执行migrate,该操作多余且可能干扰表初始化。建议移除:

@pytest.fixture(scope='session')
def django_db_setup(delete_db, django_db_blocker):
    print("django_db_setup")
    with django_db_blocker.unblock():
        call_command('migrate', '--noinput')
    yield

3. 测试用例断言密码拼写错误

测试用例中断言的密码Admninqwe1.与传入的Adminqwe1.不一致,会导致断言失败。

修复:
修正断言中的密码:

assert user.check_password('Adminqwe1.') is True

4. autouse=True引发的执行顺序问题

user_client和user均为autouse=True的session级fixture,可能存在执行顺序不稳定的情况。建议移除user_client的autouse=True,仅在需要的测试用例中显式调用。

5. "No tables found"提示说明

该提示是pytest-django初始化阶段的临时检测结果,后续migrate已经完成表创建,修复上述错误后,测试正常运行时该提示不会影响功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:13:12