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

Django测试间数据库未更新:创建与更新测试数据无法互通

问题原因

Django的TestCase类默认会为每个测试方法启动独立的数据库事务,测试方法执行完毕后自动回滚事务。这就导致:

  • test_create_object里创建的对象,在该方法结束后会被回滚,不会持久化到数据库
  • test_update_object运行在全新的数据库上下文里,自然找不到前一个测试创建的对象
解决方案

方案一:合并关联测试(推荐)

如果创建和更新是强关联的测试逻辑,直接将两个步骤放在同一个测试方法中,确保操作在同一个事务内执行:

from unittest import TestCase

class QuantsTests(TestCase):
    def setUp(self):
        self.factory = RequestFactory()

    def test_create_and_update_object(self):
        # 创建对象
        obj = Object()
        obj.name = "123456789"
        obj.save()
        
        # 执行更新并验证
        target_obj = Object.objects.get(name="123456789")
        target_obj.name = "updated_123"
        target_obj.save()
        
        # 确认更新生效
        updated_obj = Object.objects.get(name="updated_123")
        self.assertEqual(updated_obj.name, "updated_123")

方案二:用setUp初始化测试数据

如果多个测试都需要用到同一个基础对象,把创建逻辑移到setUp方法中——setUp会在每个测试方法执行前运行,每个测试都会拥有独立的对象实例:

from unittest import TestCase

class QuantsTests(TestCase):
    def setUp(self):
        self.factory = RequestFactory()
        # 每个测试前创建对象
        self.test_obj = Object()
        self.test_obj.name = "123456789"
        self.test_obj.save()

    def test_create_object(self):
        # 验证对象创建成功
        self.assertTrue(Object.objects.filter(name="123456789").exists())

    def test_update_object(self):
        # 直接使用setUp中创建的对象进行更新
        self.test_obj.name = "updated_123"
        self.test_obj.save()
        
        # 验证更新结果
        updated_obj = Object.objects.get(id=self.test_obj.id)
        self.assertEqual(updated_obj.name, "updated_123")

方案三:使用TransactionTestCase(不推荐)

如果必须让测试间共享数据库状态,可以用TransactionTestCase替代TestCase——它不会自动回滚事务,但需要手动清理测试数据,避免测试间互相污染:

from django.test import TransactionTestCase

class QuantsTests(TransactionTestCase):
    def setUp(self):
        self.factory = RequestFactory()

    def test_create_object(self):
        obj = Object()
        obj.name = "123456789"
        obj.save()

    def test_update_object(self):
        obj = Object.objects.get(name="123456789")
        obj.name = "updated_123"
        obj.save()
        
    # 手动清理测试数据,防止影响其他测试
    def tearDown(self):
        Object.objects.all().delete()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:48:21