【问题标题】:How do you unit test formsets in Django?你如何在 Django 中对表单集进行单元测试?
【发布时间】:2013-05-08 19:01:25
【问题描述】:

好的,所以我需要对视图进行单元测试,更精确的形式是在视图中。所以我创建了这样一个单元测试。

class ViewTest(TestCase):
    fixtures = ['fixture.json']
    def setUp(self):
        self.client = Client()
    def test_company_create(self):
        post_data = {
            'form-0-user': '',
            'form-0-share': '',
            'form-TOTAL_FORMS': 1,
            'form-INITIAL_FORMS': 0,
            'form-MAX_NUM_FORMS': 10
        }
    resp = self.client.post('/company/create/', post_data)
    self.assertFormError (resp, 'shareholder_formset', 'share', 'This field is required.')
    self.assertFormError (resp, 'shareholder_formset', 'user', 'This field is required.')

当然我得到一个错误

AttributeError: 'ShareholderFormFormSet' 对象没有属性 '字段'

因为 formset 里面有表单,而不是字段.....那么测试 formset 的正确方法是什么?

【问题讨论】:

  • @alecxe 这个问题的相似之处仅在于它也与表单集和单元测试有关...@Viktor 仅测试ShareholderForm 怎么样?看起来这就是你试图用你的断言做的事情......
  • 您在这个“单元”测试中同时测试视图和表单。无需执行 POST 即可测试表单。请参阅A Guide to Testing in Django #2中的“测试表格”部分
  • @gertvdijk 问题是,我在一个视图中有一个表单和一个表单集。基本上,当表单集数据和其他表单数据通过默认验证时,我会在视图中比较来自这些表单的数据,如果不匹配,那么我会手动在视图中引发错误。我这样做只是因为没有其他方法可以比较来自不同表单的数据,在我的情况下是一个表单和我的表单集......所以是的,如果你不比较来自不同表单的数据,并且不需要测试表单从某种意义上说,就我而言,它不是那样工作的。
  • @alecxe 这些完全是两个不同的问题。

标签: django unit-testing formset


【解决方案1】:

这是一个功能测试(因为你浏览了视图,如果你保存它,可能会请求模型等)。

对于表单,django-webtest 更容易使用;您不必担心这些细节: https://pypi.python.org/pypi/django-webtest

【讨论】:

    【解决方案2】:

    正如您所指出的,assertFormError 中的表单名称参数实际上只是 response.context_data 中的一个键。您使用的键返回表单集中的表单列表。因此,正如您所发现的,它不适用于 assertFormError。

    一种选择是使用 assertEqual 并直接进行比较。比如:

    self.assertEqual(response.context_data[u'shareholder_formset'][form_index].errors['share'], 'This field is required.')
    

    我还想提一下,我的 IDE (PyCharm) 对解决这个问题有很大帮助。我正在研究类似的问题。打开调试器,在调用 post() 之后放置一个断点并检查响应,给出了解决方案。

    【讨论】:

      【解决方案3】:

      Django 现在已经实现了assertFormsetError

      django-basetestcase 有一个功能,除了view 之外,您还可以测试formset,而不需要response

      formset = MyFormSet(formset_data)
      
      self.formset_error_test(
          formset,
          form_index=3,
          field='my_field',
          message='My error message.'
      )
      

      【讨论】:

      • 不要发布工具或库的链接作为答案。在答案本身中展示how it solves the problem。添加演示后,请edit 回答,并标记为取消删除。
      猜你喜欢
      • 2018-10-09
      • 2010-09-07
      • 2017-06-10
      • 2010-10-04
      • 2012-10-29
      • 1970-01-01
      • 2013-09-29
      • 2012-08-18
      • 1970-01-01
      相关资源
      最近更新 更多