第一次测试用例运行后,Django DB记录消失

时间:2017-06-01 12:15:45

标签: python django unit-testing django-rest-framework

我正在开发一个基于Django REST Framework的项目。所以我需要为我的REST API编写一些测试用例。

我已经编写了一些从标准DRF APITransactionTestCase 继承的基本类(我们称之为 BaseAPITestCase )。

在这个课程中,我已经定义了 setUp 方法,我正在创建一些属于某些组的测试用户(我正在使用 UserFactory 用FactoryBoy写的)。

当我运行我的测试时,第一个(第一个类的第一个测试用例方法)成功创建了一个具有指定组的用户,但其他人没有(其他测试用例方法) 相同类)。

目前,DB中不存在用户组。似乎在每个新的测试用例运行时都会从DB中删除已存在的记录。但它是如何第一次起作用的呢?

我已经阅读过Django测试文档,但无法弄清楚为什么会发生这种情况......任何人都可以解释一下吗?

主要问题是我应该做些什么来使这些测试有效

我应该创建一次用户并将其存储在对象变量中吗?

我应该添加一些参数来保存用户组数据吗?

或者我应该将用户组添加到灯具?在这种情况下,我该如何正确创建这个夹具? (所有相关模型,例如权限和内容类型)

简化的插图源代码:

from rest_framework.test import APITransactionTestCase    

class BaseAPITestCase(APITransactionTestCase):

    def setUp(self):
        self.user = UserFactory(
            username='login',
            password='pass',
            group_names=('admin', )
        )
        self.client = APIClient()
        self.client.force_login(self.user)

    def tearDown(self):
        self.client.logout()    

class CampaignListTest(BaseAPITestCase):

    def test_authorized_get(self):
        # successfully gets user groups from DB

    def test_authorized_post(self):
        # couldn't find any groups

1 个答案:

答案 0 :(得分:5)

TransactionTestCase是测试交易的测试用例。因此,它明确地不使用事务来隔离测试,因为这会干扰正在测试的事务的行为。

要隔离测试,TransactionTestCase通过截断所有表来回滚数据库。这是不使用事务的最简单,最快速的解决方案,但是您注意到这将删除所有数据,包括在post_migrate信号接收器中生成的组。您可以在类上设置serialized_rollback = True,在这种情况下,它将序列化对数据库的所有更改,并在每次测试后反转这些更改。但是,这显着较慢,并且通常会大大增加运行测试套件所需的时间,因此这不是默认值。

TestCase没有此限制,因此它将每个测试用例包装在一个事务中,并将每个单独的测试包含在一个保存点中。使用事务和保存点回滚很快,并允许您保留事务或保存点开始时的数据。因此,最好尽可能使用TestCase

这扩展到DRF的APITransactionTestCaseAPITestCase,它只是继承了Django的测试用例。