如何让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
相关产品推荐
相关产品推荐

