Django Rest Framework测试是否使用模拟数据库?POST端点测试问询
关于Django APITestCase数据库使用的疑问解答
嘿,完全不用担心测试会污染你的现有数据库!我来给你把这个机制讲明白:
Django测试类的数据库隔离逻辑
Django的APITestCase(以及所有继承自TestCase的测试类)默认会自动创建独立的临时测试数据库,和你的开发/生产数据库彻底隔离:
- 测试启动时,Django会根据你
settings.py里的数据库配置,生成一个专属测试库(通常是主库名加_test后缀,比如主库叫myapp_db,测试库就是myapp_db_test) - 每个测试方法执行前,会自动执行数据库迁移,把你的模型结构同步到这个临时库
- 你测试代码里所有的数据库操作(比如
Platform.objects.count())全都是在这个临时库里进行的 - 测试结束后,Django会自动清理这个测试库:默认是回滚事务(速度更快),也可以配置成直接删除整个库,确保没有任何测试数据残留,绝对不会影响你的真实数据库
针对你的测试代码
看你写的这段测试逻辑:
class APITests(APITestCase): def test_job_start(self): url = '/api/v1/job_start/' response = self.client.post(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Platform.objects.count(), 1) self.assertEqual(Platform.objects.get().name, 'andr') self.assertEqual(CdTool.objects.count(), 1) self.assertEqual(CdTool.objects.get().name, 'https://jenkins-andr.test.com') self.assertEqual(Job.objects.count(), 1) self.assertEqual(Job.objects.get().name, 'ANDR_master_CI') self.assertEqual(JobExecution.objects.count(), 1) self.assertEqual(JobExecution.objects.get().build_id, '3500') # Send the same payload, make sure no duplicate records are created response = self.client.post(url, data, format='json') self.assertEqual(Platform.objects.count(), 1) self.assertEqual(CdTool.objects.count(), 1) self.assertEqual(Job.objects.count(), 1) self.assertEqual(JobExecution.objects.count(), 1)
你两次POST请求的所有数据库断言,都是在临时测试库里执行的,完全不会触碰你现有的真实数据。而且测试结束后,这个临时库会被自动销毁,下次运行测试又是全新的干净环境。
额外小提示
- 你可以在测试运行时观察控制台输出,Django会打印创建测试数据库、执行迁移的日志,能直观看到测试用的是哪个库
- 除非有特殊需求(非常不推荐),不要修改
settings.py里的TEST配置指向真实数据库,那才会导致数据污染 APITestCase提供的self.client是模拟的HTTP客户端,发送的请求不会打到真实服务上,完全是在测试环境内部模拟的
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

