【问题标题】:testing django: reason for unexpected http status code测试django:意外http状态码的原因
【发布时间】:2014-07-01 11:12:45
【问题描述】:

我们的 django 应用程序中有很多单元。

但是如果由于状态码不匹配而导致测试失败:

Traceback (most recent call last):
  File "/home/foo_eins_di514/src/foo-time/foo_time/tests/EditTest.py", line 813, in test_web_entry_with_unclassified_activity
    self.assertEqual(200, response.status_code, url)
  File "/usr/lib64/python2.7/unittest/case.py", line 494, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/usr/lib64/python2.7/unittest/case.py", line 487, in _baseAssertEqual
    raise self.failureException(msg)
AssertionError: /foo_eins_di514/modtime/calendar/entry/view/172/

.... 完全不知道错误的退出状态是在哪里创建的。

对于大型应用程序,可能需要一些时间才能找到创建存在状态的问题根源,因为退出状态也可以在中间件中创建。

任何提示如何使它更可测试?

测试看起来像这样:

url=reverse(view_name, kwargs=dict(id=entry.id))
response=client.get(url)
self.assertEqual(200, response.status_code, url)

【问题讨论】:

  • 首先,您能否发布一个示例测试...可能让人们建议如何更好地进行单元测试。其次,就我个人而言,我发现如果我返回 200,我很少专门检查 status_code == 20,而是执行 self.assertContains(response,"some text I'm looking for"),这隐含也做了200检查。 YMMV。
  • @Foon 我添加了测试的相关sn-p。

标签: python django unit-testing httprequest


【解决方案1】:

听起来您应该将测试拆分为适当的单元测试并测试更小的代码单元。使用 Django 的 request factory 并仅测试视图代码。或者将您的视图拆分为更小的函数并单独测试它们。

使用 Django 的测试客户端更像是集成测试而不是单元测试,因为它测试 url 路由、数据库、中间件、模板等

【讨论】:

    【解决方案2】:

    您将来自 assertEqual 的有用消息替换为不太有用的消息,即失败的 URL(assertEqual 的第三个参数)。

    您这样做是因为同一个测试方法测试多个 URL。这是一个不好的做法。每种测试方法都应该测试一件事。 DRY 不适用于单元测试(或者至少更重要的是每个测试方法都测试一件事,而且只测试一件事)。

    假设您知道有问题的状态码,更容易找到它的来源。假设它是 404,那么,也许找不到对象,也许是 300 左右,也许您没有适当的权限并被重定向到登录页面。

    任何真正的编程错误都会因正常异常和有用的堆栈跟踪而失败。

    如果您关心特定视图内的逻辑,请将逻辑拆分为多个可测试单元。

    在这种特殊情况下,我的钱将用于错误的 PK 或缺少权限。

    关于你的嘲讽,试试这样的:

    with patch.object(HttpResponseBase, '__init__', None):
        response = client.get(url)
    

    【讨论】:

      【解决方案3】:

      我使用这个解决方案找到了问题:

      import django
      django.http.response.HttpResponseBase.__init__=None
      response=client.get(url)
      

      这会产生一个堆栈跟踪,我可以在其中看到 HttpResponse 的创建位置。

      当然这只是调试的临时解决方案。我对 mock 进行了同样的尝试,但失败了,因为我还不是 mock 专家。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-28
        • 1970-01-01
        • 1970-01-01
        • 2021-06-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多