Django事务测试用例在sqlite数据迁移时引发IntegrityError
我正在尝试把一个使用 LiveServerTestCase 的 Django 1.6 项目迁移到 Django 1.7。为了这个迁移,我把初始数据的设置转换成了数据迁移。但是这样一来,我的所有实时服务器测试都失败了,因为数据被清空了。后来我发现了 TransactionTestCase 的 serialized_rollback 选项,并把它加到了我的测试类中。不过现在,当我运行测试时,出现了以下错误:
sqlite3.IntegrityError: UNIQUE constraint failed: django_content_type.app_label, django_content_type.model
我在这里的一个示例应用中复现了这个问题: https://github.com/tctimmeh/djangomigrate
模型:
class SomeData(Model):
value = IntegerField()
数据迁移:
def createData(apps, schema_editor):
SomeData = apps.get_model('mtestapp', 'SomeData')
db_alias = schema_editor.connection.alias
SomeData.objects.using(db_alias).bulk_create([
SomeData(value = 1),
])
class Migration(migrations.Migration):
dependencies = [
('mtestapp', '0001_initial'),
]
operations = [
RunPython(createData)
]
还有测试:
class TestIt(TransactionTestCase):
serialized_rollback = True
def test_one(self):
self.assertEqual(1, SomeData.objects.all().count())
def test_two(self):
self.assertEqual(1, SomeData.objects.all().count())
其中一个测试通过了,另一个则引发了上面提到的 IntegrityError。你知道这可能是什么原因吗?
编辑:我进一步研究了一下,发现 django.contrib.contenttypes 应用有一个在测试数据库被清空后运行的 post_migrate 管理命令。有没有办法阻止这个命令运行呢?
3 个回答
0
你需要将你的应用程序添加到 available_apps 中,这样Django就会像只使用这个应用里的模型一样。在你的测试案例中,你可以这样做:
class TestIt(TransactionTestCase):
serialized_rollback = True
available_apps = ['mtestapp']
def test_one(self):
self.assertTrue(True)
def test_two(self):
self.assertTrue(True)
0
我在不同的情况下遇到了同样的问题。
我把 serialized_rollback = True
去掉了,然后在 setUp() 方法里手动添加了一些测试数据。
0
这个问题在Django 1.9版本中已经修复了:https://code.djangoproject.com/ticket/23727
在更早的版本中,我通过在每次测试之前重新创建我的静态数据来解决这个问题。