如何在DRF项目中配置测试数据库并解决批量测试失败问题?
问题分析
核心问题有两点:
- Django默认会给
default数据库生成带test_前缀的测试库,但Djongo在批量测试时无法正确删除这个测试库,导致后续测试因数据库状态异常失败。 - 你配置了
test数据库,但Django测试时不会自动切换到该库,仍会默认使用default的测试实例。
解决方案
1. 强制测试时使用PostgreSQL测试库
方式一:通过环境判断切换默认数据库
修改settings.py,当检测到执行测试命令时,将默认数据库替换为你配置的PostgreSQL测试库:
import sys import os # 原有数据库配置 DATABASES = { 'default': { 'ENGINE': 'djongo', 'NAME': 'my_project_name', 'CLIENT': { 'host': os.environ[DB_HOST], } }, 'test': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'test_mytestdatabase', 'USER': 'mytestdatabaseuser', 'PASSWORD': 'mytestpassword', 'HOST': 'localhost', 'PORT': '5432', } } # 测试时自动切换默认数据库 if 'test' in sys.argv or os.environ.get('RUNNING_TESTS'): DATABASES['default'] = DATABASES.pop('test')
执行python3 manage.py test时,默认数据库会自动切换为PostgreSQL测试库,彻底避开Djongo的测试数据库删除问题。
方式二:通过TEST节点覆盖默认库配置
给default数据库添加TEST配置,指定测试时直接使用PostgreSQL:
DATABASES = { 'default': { 'ENGINE': 'djongo', 'NAME': 'my_project_name', 'CLIENT': { 'host': os.environ[DB_HOST], }, # 测试阶段使用PostgreSQL 'TEST': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'test_mytestdatabase', 'USER': 'mytestdatabaseuser', 'PASSWORD': 'mytestpassword', 'HOST': 'localhost', 'PORT': '5432', } } }
这种方式无需额外环境判断,Django会自动在测试时使用TEST节点下的配置。
2. 若坚持用Djongo测试的兼容方案
如果不想切换数据库,可手动重写测试类的清理逻辑,避免Django删除整个数据库:
from django.test import TestCase from pymongo import MongoClient import os class BaseMongoTest(TestCase): def setUp(self): self.mongo_client = MongoClient(os.environ[DB_HOST]) self.test_db = self.mongo_client['test_my_project_name'] def tearDown(self): # 清空所有集合而非删除数据库 for coll_name in self.test_db.list_collection_names(): self.test_db[coll_name].delete_many({})
所有测试类继承BaseMongoTest,用手动清空集合替代数据库删除操作。
3. 额外测试配置建议
- 提前创建
test_mytestdatabase数据库,确保mytestdatabaseuser拥有创建、修改、删除表的权限。 - 测试时添加
--keepdb参数,复用现有测试数据库,减少数据库重建/删除操作:python3 manage.py test test.path --keepdb - 若用CI/CD环境,可设置
RUNNING_TESTS环境变量,确保配置切换准确。
内容的提问来源于stack exchange,提问作者Mike D Hovhannisyan
相关产品推荐
相关产品推荐

