在django单元测试中使用用户模型的问题

the*_*rty 21 python django unit-testing django-testing

我有以下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):
        ...
Run Code Online (Sandbox Code Playgroud)

当我运行我的测试时,testA将成功通过但在testB启动之前,我收到以下错误:

IntegrityError: column username is not unique
Run Code Online (Sandbox Code Playgroud)

很明显,它试图self.u1在每个测试用例之前创建并发现它已经存在于数据库中.如何在每个测试用例之后正确清理它以便后续情况正确运行?

Dav*_*cic 29

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()
Run Code Online (Sandbox Code Playgroud)

我还建议使用信号创建用户配置文件,post_save除非您真的想要为每个用户手动创建用户配置文件.

删除评论的后续行动:

来自Django文档:

当Django删除一个对象时,它会模拟SQL约束ON DELETE CASCADE的行为 - 换句话说,任何具有 指向要删除的对象的外键的对象都将随之删除.

在您的情况下,用户配置文件指向用户,因此您应该首先删除用户以同时删除配置文件.


Chr*_* W. 10

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

在每次测试之后转储数据库是一个好习惯,这样你就可以确定测试是否一致,但请注意,这些额外的开销会导致测试运行速度变慢.

请参阅"编写测试"Django文档中的" 警告"部分.