2010-05-15 138 views
18

我有一个是给我的错误以下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每个测试用例前,发现它已经存在于数据库中。如何在每个测试用例之后正确清理它,以便后续案例正确运行?

回答

27

setUptearDown单元测试中的方法在每个测试用例之前和之后被调用。定义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() 

我也使用post_save信号,除非你真的想手动创建的用户配置文件为每个用户奉劝create user profiles。在删除评论

后续

Django docs

When Django deletes an object, it emulates the behavior of the SQL constraint ON DELETE CASCADE -- in other words, any objects which had foreign keys pointing at the object to be deleted will be deleted along with it.

在你的情况下,用户配置文件指向用户,所以你应该先删除该用户删除的配置文件同时。

+0

谢谢!我现在遇到的问题是,当我删除up1时,删除不会级联和删除u1,即使我已将User指定为UserProfile的外键。例如'user = models.ForeignKey(User,unique = True)' – theycallmemorty 2010-05-15 15:00:16

+0

实际上,您应该删除用户以一次性级联和删除用户配置文件,或者先删除用户配置文件,然后再删除用户。 – 2010-05-15 15:04:56

+0

Bah ...我读的不是在文档中,但由于某种原因弄糊涂外键所指向的方向... – theycallmemorty 2010-05-15 16:09:00

2

准确地说,setUp存在的目的是在每个测试用例之前运行一次。

相反的方法,即各测试用例之后运行一次之一,被命名为tearDown:这就是你删除self.u1等(比如通过只调用self.u1.delete(),除非你有另外补充专门的清理要求,只是删除对象)。

8

如果你想让django在每次测试运行后自动刷新测试数据库,那么你应该扩展django.test.TestCase而不是django.utils.unittest.TestCase(就像你现在正在做的那样)。

在每次测试后转储数据库是一种很好的做法,所以您可以确保测试是一致的,但请注意,由于此额外开销,您的测试将运行得更慢。

查看警告部分中的"Writing Tests" Django Docs