能,但必须通过pytest-django插件加载django配置和数据库上下文;它自动执行django.setup()、加载settings、创建内存数据库,并支持函数式测试与事务隔离,无需继承testcase。

pytest-django 能直接测试 Django ORM 模型吗?
能,但必须让 pytest 知道 Django 的配置和数据库上下文。pytest 本身不加载 Django,pytest-django 是桥梁——它接管 pytest 的启动流程,提前运行 django.setup()、加载 settings、创建测试数据库(默认使用内存 SQLite),之后你写的模型测试才能调用 save()、objects.create() 等操作而不报 AppRegistryNotReady。
- 必须在项目根目录下有
pytest.ini或pyproject.toml声明DJANGO_SETTINGS_MODULE - 不要手动调用
django.setup():pytest-django 已做,重复调用会触发警告甚至崩溃 - 测试文件名必须匹配 pytest 默认规则(如
test_<em>.py</em>或_test.py),否则不会被发现
如何写一个最简可行的模型测试?
从定义模型开始,比如 books/models.py:
from django.db import models <p>class Book(models.Model): title = models.CharField(max_length=100) isbn = models.CharField(max_length=13, unique=True)</p>
对应测试 tests/test_models.py:
from books.models import Book <p>def test_book_creation(): book = Book.objects.create(title="Test Book", isbn="9780262033848") assert book.pk is not None assert book.title == "Test Book" assert Book.objects.count() == 1</p>
- 不需要
TestCase类或setUpTestData:pytest-django 支持函数式测试,更轻量 - 所有数据库操作自动在事务内运行(每个测试函数独享事务,结束后回滚),无需手动清理
- 若需访问真实数据库(如调试慢查询),可加装饰器
@pytest.mark.django_db(transaction=True),但默认不推荐
常见报错:django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
这是最典型的信号:pytest-django 没生效。
- 检查是否安装了
pytest-django(不是只装了pytest):pip install pytest-django - 检查
pytest.ini是否存在且内容正确:[tool:pytest] DJANGO_SETTINGS_MODULE = "myproject.settings" python_files = tests.py test_*.py *_tests.py
- 检查
manage.py同级是否存在settings.py(或对应模块路径是否拼写错误) - 运行命令必须是
pytest,不是python -m pytest(后者有时绕过插件注册)
什么时候必须用 @pytest.mark.django_db?
几乎所有涉及 ORM 的测试都需要它,但规则比直觉更细:
- 如果测试函数里没碰数据库(例如只检查模型字段定义、
<strong>str</strong>返回值),可以不加标记,pytest-django 会跳过 DB 初始化 - 如果用了
Book.objects.filter(...)、.save()、.delete(),就必须加@pytest.mark.django_db - 多个测试函数共用数据?别依赖“上一个测试留下的记录”——每个测试默认隔离。如真需共享,用
@pytest.mark.django_db(transaction=True)+ 显式transaction=True,但会显著拖慢速度
Django 模型测试真正难的不是语法,而是理解 pytest-django 如何接管生命周期:它不改模型代码,只改测试执行时的环境注入时机。漏掉配置项、错放标记、或误信“不加也能跑”的侥幸,都会让测试在 CI 上突然失败。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











