pytest-django 更常用因其断言直观、fixture灵活、插件生态成熟,且能复用Django配置;它默认事务级隔离提速测试,支持fixture注入数据、绕过CSRF/登录校验,并提供数据库复用等优化手段。

pytest-django 为什么比 Django 自带 test runner 更常用
因为 pytest 的断言更直觉、fixture 机制更灵活、插件生态更成熟,而 pytest-django 能复用 Django 的配置(比如 settings.py 和数据库配置),不用重写测试启动逻辑。Django 自带的 TestCase 在快速验证单个视图或模型时够用,但一旦涉及跨模块依赖注入、参数化测试、或需要和第三方 pytest 插件(如 pytest-cov)协作,就明显吃力。
常见错误现象:django.core.exceptions.ImproperlyConfigured: Requested setting DATABASES, but settings are not configured —— 这通常是因为没正确加载 Django 配置,或者 pytest 启动时没识别到 pytest-django 插件。
- 确保项目根目录有
pytest.ini或pyproject.toml,且已声明django_settings_module - 不要手动调用
django.setup();pytest-django会在收集测试前自动完成 - 避免在测试文件顶部 import models 后立刻访问
Model._meta.db_table等触发 ORM 初始化的代码——这会抢在 Django 配置加载前报错
怎么写一个能跑通的 model 测试用例
核心是让 pytest 知道该用哪个数据库、是否要迁移、以及如何复用 Django 的测试数据库生命周期。默认情况下,pytest-django 会为每个测试函数创建事务级隔离(比 Django 默认的每个类一个数据库更快),但不执行真实 migration,而是用 manage.py makemigrations --dry-run 推导 schema。
使用场景:验证模型字段约束、自定义 save() 行为、或 get_absolute_url() 返回值。
立即学习“Python免费学习笔记(深入)”;
强戈环形山: q15040409-刻画家功能概述强戈环形山: q15040409-刻画家是一项面向实际任务的技能,主要用于平顶山: 维西翁: 1:1.0. 塔格斯: rap.github: 自动化。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。核心要点使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。从功能定位来看,该
- 测试类不必继承
TestCase,直接用普通 class +def test_*函数即可 - 用
pytest.fixture注入测试数据比在setUp里硬编码更清晰,例如:@pytest.fixture def user(): return User.objects.create_user(username="test", email="t@example.com") - 避免在测试中调用
Model.objects.create()后立刻查库验证——事务未提交时可能查不到;改用refresh_from_db()或依赖 pytest-django 的自动事务回滚机制
测试视图时怎么绕过 CSRF 和登录校验
直接用 Client 发请求最轻量,但默认会触发 CSRF 检查和中间件链。你不需要真的启动服务器,也不该 mock 整个 request 对象——pytest-django 提供了更贴近真实流程的方式。
常见错误现象:403 Forbidden(CSRF 失败)或 302 Redirect to /login/(未登录跳转)。
- 对需要登录的视图,用
client.login(username=..., password=...),它会自动设置 session 和 cookies - 对 API 视图(尤其是 DRF),优先用
APIClient并调用.force_authenticate(user=user),跳过 session 和 token 校验链 - 如果只是想测视图逻辑而非中间件,可在测试函数上加装饰器:
@pytest.mark.django_db(transaction=True)(慎用,影响速度),或临时禁用中间件(不推荐)
为什么测试数据库跑得慢,以及怎么提速
慢通常不是因为 SQL 本身,而是每次测试都重建表结构、重复运行 migration、或 fixture 加载过大。Django 默认为每个测试类重建数据库,而 pytest-django 默认按函数粒度隔离,但若用了 transaction=True 或大量 LiveServerTestCase 类型,就会退化。
性能影响:一个含 50 个测试函数的文件,若每个都走完整 migrate,可能多花 3–5 秒。
- 用
--reuse-db参数让 pytest 复用测试数据库(首次仍需 migrate,后续跳过) - 把固定测试数据从
fixtures改成pytest.fixture+bulk_create,避免 JSON 反序列化开销 - 禁用非必要 app 的 migrations:在
pytest.ini中设django_migrations=false,再用django.test.utils.get_runner(...).setup_databases()手动建表(仅限简单项目)
最容易被忽略的是:很多人在 conftest.py 里写了全局 autouse=True 的 fixture,结果每个测试都无意识地创建了一堆对象——这种隐式副作用比慢更危险。

















