在 Django + DRF 项目中后期引入自动化测试:设置、需求与最佳实践 - 第1部分

发布: (2025年12月12日 GMT+8 11:01)
5 min read
原文: Dev.to

Source: Dev.to

许多 Django REST Framework 项目在开始时会快速开发功能,却没有自动化测试套件。起初这看起来很高效,但随着外键增多、序列化器变得嵌套以及系统复杂度提升,手动测试变得脆弱且极其耗时。

本系列的两篇文章将完整演示如何 在已有的 Django REST Framework 项目中引入 pytest,即使你已经深入开发也不例外。

第 1 部分涵盖

  • 为什么 pytest 是 Django + DRF 的理想选择
  • 安装 pytest 并配置项目级设置
  • 创建单独的测试设置文件
  • 为 PostgreSQL 设置专用的测试数据库
  • 为 API 客户端和测试用户编写 fixtures
  • 安全地处理自定义用户模型
  • 为可靠运行测试做好项目准备

第 2 部分将展示基于 Blog → Writer → Category → SocialMediaMeta 场景的真实测试案例。


为什么要在后期添加测试?

许多团队会把测试推迟到:

  • 模型已基本稳定
  • 视图和序列化器开始积累业务逻辑
  • 手动测试变得缓慢或容易出错
  • 重构风险增大
  • Bug 频繁出现
  • 新成员加入时的上手成本过高

好消息是:只要正确分离测试配置,pytest 完全可以干净地集成到大型、活跃的 Django 项目中

安装 pytest 及所需插件

pip install pytest pytest-django pytest-cov Faker

这些工具提供:

  • pytest – 快速、表达力强的测试框架
  • pytest-django – Django ORM、fixture、数据库初始化等支持
  • pytest-cov – 代码覆盖率统计
  • Faker – 生成随机测试数据

在项目根目录创建 pytest.ini

[pytest]
DJANGO_SETTINGS_MODULE = project.settings.test
python_files = tests.py test_*.py *_tests.py
addopts = --reuse-db -x

关键点

  • 明确指向 测试设置 文件。
  • --reuse-db 能显著加快测试速度。
  • -x 在首次失败后立即停止(可选,但在早期非常实用)。

创建 settings/test.py

from .local import *

DATABASES["default"]["NAME"] = "test_db"
AUTH_PASSWORD_VALIDATORS = []

TEST_USER = {
    "id": 999,
    "email": "testuser@example.com",
}

(a) 独立的数据库

测试时绝不能触及开发数据库。

(b) 禁用密码校验器

避免因密码复杂度要求导致测试失败。

(c) TEST_USER

用于绕过复杂的注册流程(OTP、邮件验证、自定义用户管理器逻辑)。

PostgreSQL:创建专用的测试数据库

CREATE DATABASE test_db;
GRANT ALL PRIVILEGES ON DATABASE test_db TO your_db_user;
ALTER DATABASE test_db OWNER TO your_db_user;

手动创建数据库可以避免出现令人头疼的:

permission denied to create database

添加 tests/ 目录结构

tests/
│── __init__.py
│── conftest.py
│── test_blog_creation.py
│── test_blog_listing.py
│── test_nested_blog_response.py
│── test_signals_blog_metadata.py

这里的关键文件是 conftest.py

创建包含关键 Fixtures 的 conftest.py

import pytest
from django.contrib.auth import get_user_model
from blogs.models import Writer, Category

@pytest.fixture
def test_user(db, settings):
    User = get_user_model()
    data = settings.TEST_USER
    return User.objects.create(
        id=data["id"],
        email=data["email"],
        is_active=True,
    )

@pytest.fixture
def api_client(test_user):
    from rest_framework.test import APIClient
    client = APIClient()
    client.force_authenticate(test_user)
    return client

@pytest.fixture
def writer(db):
    return Writer.objects.create(
        name="Jane Writer",
        email="jane@example.com",
    )

@pytest.fixture
def category(db):
    return Category.objects.create(
        title="Technology",
        slug="tech",
    )

这些 fixtures 提供:

  • 已认证的 API 客户端(无需登录/OTP 步骤)
  • 可复用的测试用户
  • 稳定的外键依赖

第一次运行测试

pytest -s

如果配置无误,pytest 将创建测试数据库并成功运行所有测试。

第 2 部分预告:真实的 DRF 测试用例

在下一节我们将讨论:

  • Blog + Writer + Category + SocialMediaMeta 示例模型
  • 嵌套序列化器
  • 外键创建测试
  • 信号与反向关系
  • 错误校验测试
  • 嵌套 JSON 结构的测试
  • 认证请求的测试
Back to Blog

相关文章

阅读更多 »