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

如何让pytest结合Django REST Framework访问真实django_db而非测试库

让pytest访问真实Django数据库的解决方案

首先得明确:@pytest.mark.django_db默认会创建独立的测试数据库,和你的开发/生产真实数据库完全隔离——这是测试的最佳实践,既能避免测试影响真实数据,也能保证测试环境的一致性。但如果确实需要让测试直接访问真实数据库,我们可以通过以下方式实现:

1. 全局修改pytest配置(简单直接)

在项目根目录创建或编辑pytest.ini文件,添加以下配置:

[pytest]
DJANGO_SETTINGS_MODULE = your_project.settings  # 替换为你的项目settings路径
django_db_createdb = False  # 禁止创建新的测试数据库
django_db_keepdb = True     # 保留现有数据库(即你的真实库)

这样pytest就会直接使用你settings里配置的真实数据库,而非创建临时测试库。

2. 局部自定义数据库配置(更灵活)

如果不想全局修改配置,只想让特定测试访问真实数据库,可以在conftest.py中定义一个自定义fixture来覆盖数据库配置:

import pytest
from django.conf import settings

@pytest.fixture(scope="session")
def use_real_database():
    # 备份原数据库配置,测试结束后恢复
    original_db_config = settings.DATABASES['default'].copy()
    # 替换为真实数据库的配置
    settings.DATABASES['default'] = {
        'ENGINE': 'django.db.backends.postgresql',  # 替换为你的数据库引擎(mysql/sqlite等)
        'NAME': 'your_real_db_name',
        'USER': 'your_db_user',
        'PASSWORD': 'your_db_password',
        'HOST': 'localhost',
        'PORT': '5432',  # 对应你的数据库端口
    }
    yield
    settings.DATABASES['default'] = original_db_config

然后在你的测试中引入这个fixture:

import pytest
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient

@pytest.mark.django_db
def test_airport_list_real(use_real_database):
    client = APIClient()
    response = client.get(reverse('query_flight:airports-list'))
    assert response.status_code == 200
    assert len(response.json()) > 0

必须注意的风险

  • 数据安全:如果测试中有写入/修改/删除操作,会直接影响真实数据库的数据,务必确保测试是只读的,或者在测试前后备份数据。
  • 测试稳定性:测试结果会依赖真实数据的状态,一旦真实数据发生变化,测试可能失败,失去了测试的可靠性。
  • 替代方案推荐:如果只是需要测试用的真实数据,更合理的做法是将真实数据导出,在测试前导入到测试数据库中(比如用django.core.management.call_command('loaddata', 'your_data.json')),既保证测试数据的真实性,又不影响真实库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:11:54