【问题标题】:Django when to use teardown methodDjango 何时使用拆卸方法
【发布时间】:2012-02-27 01:34:52
【问题描述】:

根据文档:

另一方面,TestCase 不会截断表并重新加载 测试开始时的初始数据。相反,它包含了测试 在数据库事务结束时回滚的代码 测试。它还可以防止被测代码发出任何提交或 对数据库进行回滚操作,保证回滚在 测试结束将数据库恢复到其初始状态。在 为了保证所有 TestCase 代码都以干净的开头 数据库,Django 测试运行器首先运行所有 TestCase 测试,然后 任何其他可能改变数据库的测试(例如 doctests) 恢复到原来的状态。

如果我有一个看起来像这样的测试:

class GeneralUserCreateTest(TestCase):

    def setUp(self):
        create_roletypes()
        create_permissiontypes()
        self.client = Client()
        self.event = create_event()

    def test_create(self):
        create_url = reverse('event_user_signup', args=[self.event.slug])

        post_data = {
            'signup-account-email': 'foo@bar.com',
            'signup-account-password': 'foobar',
            'signup-account-password2': 'foobar',
            'signup-account-first_name': 'Foo',
            'signup-account-last_name': 'Bar',
        }
        response = self.client.post(create_url, data=post_data)
        self.assertEqual(response.status_code, 302)

        # check creation of user object
        self.assertEqual(User.objects.filter(email=post_data['signup-account-email']).count(), 1)
        user = User.objects.get(username=post_data['signup-account-email'])

        # user and profile objects created
        self.assertEqual(User.objects.all().count(), 1)
        self.assertEqual(Profile.objects.all().count(), 1)

        # get the first user and profile object to test against submitted field
        user = User.objects.all()[0]
        profile = Profile.objects.all()[0]
        role = Role.objects.filter(event=self.event, profiles=profile)[0]
        self.assertEqual(role.roletype.name, 'General')
        self.assertEqual(user.username, post_data['signup-account-email'])
        self.assertEqual(user.email, post_data['signup-account-email'])
        self.assertEqual(profile.first_name, post_data['signup-account-first_name'])
        self.assertEqual(profile.last_name, post_data['signup-account-last_name'])

是否仍然需要运行 teardown 方法或 TestCase 类来处理它?如果是这样,考虑到TestCase 类的可用性,什么时候应该使用teardown 方法?

【问题讨论】:

    标签: django


    【解决方案1】:

    对于数据库而言,tearDown 毫无意义,因为每个测试都在事务中运行。但是,并非测试中的所有内容都涉及数据库。您可能会测试文件创建/读取、分离进程、打开网络连接等。这些类型的事情通常需要您在完成后“关闭”它们。这就是 tearDown 的用途,即从您的 setUp 方法中清理与数据库无关的东西。 (不过,如果您实际上是直接连接到数据库,即实际的 Django 测试必须确保所有 DBAPI 工作正常,您也需要在那里进行清理。)

    【讨论】:

      【解决方案2】:

      我正在处理一个处理一些文件上传的项目,我需要删除测试创建的文件,tearDown 方法在这种情况下非常有用。

      import shutil
      
      #....
      #....
      
          def tearDown(self):
              shutil.rmtree(settings.UPLOAD_ROOT)
      

      【讨论】:

        【解决方案3】:

        如果您使用的是 MongoDB 或 Redis 等替代数据库,并且需要加载一组初始数据(“集合”),则还需要覆盖 tearDown 方法。

        http://www.belchak.com/2011/02/07/unit-testing-django-with-a-nosql-backend/

        一般来说,django.test.TestCase 在每次开始时都会进行一次完整的数据库刷新 新的测试。这意味着我们不需要像 Chris Pratt 上面提到的那样手动删除我们的 tearDown 中的对象。下一个测试设置将确保数据库是干净的。

        但是,如果我们使用 doctests 和 unittest.TestCase,则在再次运行测试之前不会刷新数据库。在测试开始时,数据库将处于之前的任何状态 测试离开。这意味着之前运行留下的任何杂散数据都会导致冲突。因此,如果我们使用 doctests 或 unittest.TestCase 进行 django 测试,清理可能是一个好习惯。

        最后,在更复杂的场景中,故意持久化测试数据库以查找特定的单元测试错误也可能有意义。

        【讨论】:

        • 我发现TestCase 并不总是刷新数据库...我不确定是什么原因造成的,但有好几次我不得不使用TransactionTestCase 来重置测试之间的数据库。
        • 我不同意你关于寻找单元测试错误的最后一点。原则上,单元测试应该是独立的,所以一切都应该包含在单元测试中,对吧?在之前或之后执行测试不应影响当前单元测试的运行。您能否解释一个可能需要在测试之间持久化数据的复杂场景示例?
        • @Calvin Cheng 如果我使用 unittest.TestCase 与 django.test.TestCase 相反(正是为了在每次测试后不必刷新数据库),那么 - 你有什么建议吗关于使用 self.assertTemplateUsed(response, 'example.html') 方法。我收到错误 TestViews' 对象没有属性 'assertTemplateUsed'。 (但如果我使用 django.test.TestCase - 没有错误。.. 但是每次都会刷新数据库。)有什么建议吗?
        猜你喜欢
        • 1970-01-01
        • 2014-07-05
        • 2012-12-14
        • 2017-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多