我有以下django测试用例,它给了我错误:
class MyTesting(unittest.TestCase):
def setUp(self):
self.u1 = User.objects.create(username='user1')
self.up1 = UserProfile.objects.create(user=self.u1)
def testA(self):
...
def testB(self):
...
当我运行测试时,testA
将成功通过,但在testB
启动之前,我会收到以下错误:
IntegrityError: column username is not unique
很明显,它试图在每个测试用例之前创建self.u1
并发现它已经存在于数据库中。如何在每个测试用例之后对其进行正确清理以便后续情况正确运行?
答案 0 :(得分:28)
setUp
和tearDown
方法。定义删除创建的用户的tearDown
方法。
class MyTesting(unittest.TestCase):
def setUp(self):
self.u1 = User.objects.create(username='user1')
self.up1 = UserProfile.objects.create(user=self.u1)
def testA(self):
...
def tearDown(self):
self.up1.delete()
self.u1.delete()
除非您真的想为每个用户手动创建用户个人资料,否则我还会建议create user profiles使用post_save
信号。
跟进:
来自Django docs:
当Django删除一个对象时,它 模拟SQL的行为 约束ON DELETE CASCADE - in 换句话说,任何具有的对象 指向对象的外键 被删除将被删除 它
在您的情况下,用户个人资料指向用户,因此您应该首先删除用户以同时删除个人资料。
答案 1 :(得分:9)
如果您希望django在每次测试运行后自动刷新测试数据库,那么您应该扩展django.test.TestCase
,而不是django.utils.unittest.TestCase
(正如您当前所做的那样)。
最好在每次测试后转储数据库,这样你可以确定测试是否一致,但请注意,这些额外开销会使测试运行速度变慢。
中的警告部分答案 2 :(得分:2)
确切地说,setUp
存在的目的在每个测试用例之前运行一次。
相反的方法,在每个测试用例后运行一次的方法,命名为tearDown
:这是你删除self.u1
等的地方(大概是通过调用{{1}除非你只是删除对象,否则除非你有补充的专业清理要求。)