Django测试用例执行时如何保留并共享测试数据?
解决Django测试中跨测试方法复用初始数据的问题
核心问题
Django自带的TestCase默认会为每个测试方法开启独立事务,测试结束后自动回滚,导致单个测试方法内创建的数据无法在其他测试方法中复用;而原生unittest.TestCase不会自动切换到测试数据库,会直接操作主库,不符合测试隔离要求。
解决方案
1. 使用类级别的setUpClass方法创建共享初始数据
将需要复用的初始数据放到setUpClass中,这个方法会在整个测试类的所有测试方法执行前仅运行一次。Django的TestCase会保证这些初始数据在每个测试方法中都能访问到——每个测试方法会基于初始数据的状态创建事务保存点,测试结束后回滚到该保存点,不会修改共享的初始数据。
修改后的测试代码示例:
from django.test import TestCase from . import models class BankServiceTest(TestCase): @classmethod def setUpClass(cls): super().setUpClass() # 创建所有测试方法共享的初始数据 cls.test_bank = models.Bank.objects.create(name='bank') cls.test_country = models.Country.objects.create(name='country', code=100) def test_bank_object_exists(self): re1 = models.Bank.objects.get(name='bank') self.assertEqual(re1.name, 'bank') def test_country_object_exists(self): # 直接复用已创建的bank数据 existing_bank = self.test_bank re1 = models.Country.objects.get(code=100) self.assertEqual(re1.name, 'country')
2. 封装通用测试基类,供大量测试用例复用
针对项目中500+依赖相同初始数据的测试用例,可以创建一个基础测试类,将共享数据的创建逻辑放到基类的setUpClass中,其他测试类直接继承该基类即可,避免重复编写数据初始化代码。
示例:
from django.test import TestCase from . import models class BaseTestWithInitialData(TestCase): @classmethod def setUpClass(cls): super().setUpClass() # 统一创建所有测试用例需要的初始数据 cls.test_bank = models.Bank.objects.create(name='bank') cls.test_country = models.Country.objects.create(name='country', code=100) # 可添加更多通用初始数据... # 业务测试类继承基类,直接使用共享数据 class BankServiceTest(BaseTestWithInitialData): def test_bank_basic_function(self): self.assertEqual(self.test_bank.name, 'bank') class CountryServiceTest(BaseTestWithInitialData): def test_country_code_validation(self): self.assertEqual(self.test_country.code, 100)
注意事项
- 必须使用Django提供的
TestCase或TransactionTestCase,而非原生unittest.TestCase,前者会自动配置并使用测试数据库,完全隔离主库数据。 - 如果需要测试方法之间共享修改后的数据(而非仅初始数据),可以使用
TransactionTestCase,但该类会在每个测试方法结束后截断所有表,而非回滚事务,因此测试方法的执行顺序会影响结果,需谨慎使用。
内容的提问来源于stack exchange,提问作者HOSSEIN
相关产品推荐
相关产品推荐

