Django:测试页面是不是已重定向到所需的 url
Posted
技术标签:
【中文标题】Django:测试页面是不是已重定向到所需的 url【英文标题】:Django : Testing if the page has redirected to the desired urlDjango:测试页面是否已重定向到所需的 url 【发布时间】:2013-02-03 18:32:03 【问题描述】:在我的 django 应用程序中,我有一个身份验证系统。因此,如果我没有登录并尝试访问某些个人资料的个人信息,我会被重定向到登录页面。
现在,我需要为此编写一个测试用例。我得到的浏览器的响应是:
GET /myprofile/data/some_id/ HTTP/1.1 302 0
GET /account/login?next=/myprofile/data/some_id/ HTTP/1.1 301 0
GET /account/login?next=/myprofile/data/some_id/ HTTP/1.1 200 6533
如何编写我的测试?这是我到目前为止所拥有的:
self.client.login(user="user", password="passwd")
response = self.client.get('/myprofile/data/some_id/')
self.assertEqual(response.status,200)
self.client.logout()
response = self.client.get('/myprofile/data/some_id/')
接下来会发生什么?
【问题讨论】:
【参考方案1】:Django 1.4:
https://docs.djangoproject.com/en/1.4/topics/testing/#django.test.TestCase.assertRedirects
Django 2.0:
https://docs.djangoproject.com/en/2.0/topics/testing/tools/#django.test.SimpleTestCase.assertRedirects
SimpleTestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='', fetch_redirect_response=True)
断言响应返回 status_code 重定向状态,重定向到 expected_url(包括任何 GET 数据),并且最终页面是收到 target_status_code。
如果您的请求使用 follow 参数,则 expected_url 和 target_status_code 将是重定向最后点的 url 和状态码链。
如果 fetch_redirect_response 为 False,则不会加载最终页面。由于测试客户端无法获取外部 URL,因此如果 expected_url 不是您的 Django 应用程序的一部分,这将特别有用。
在两个 URL 之间进行比较时,会正确处理方案。如果在我们被重定向到的位置没有指定任何方案,则使用原始请求的方案。如果存在,expected_url 中的方案是用来进行比较的方案。
【讨论】:
【参考方案2】:您也可以通过以下方式跟踪重定向:
response = self.client.get('/myprofile/data/some_id/', follow=True)
这将反映浏览器中的用户体验并断言您希望在那里找到的内容,例如:
self.assertContains(response, "You must be logged in", status_code=401)
【讨论】:
在测试中期望特定的页面内容是危险的。使非程序员(网页编辑)有可能在不知不觉中破坏测试。【参考方案3】:您可以检查response['Location']
并查看它是否与预期的网址匹配。还要检查状态码是否为 302。
【讨论】:
最适合不关心target_status_code
会是什么的情况。
直接对视图进行单元测试(不使用 Django 客户端)时,这是正确的答案。【参考方案4】:
response['Location']
在 1.9 中不存在。改用这个:
response = self.client.get('/myprofile/data/some_id/', follow=True)
last_url, status_code = response.redirect_chain[-1]
print(last_url)
【讨论】:
如果没有提供follow=True
,它是可用的。 Django(任何版本)不会删除像Location
这样的正常响应头。当follow
为True
时,将遵循重定向,自然最后的响应没有Location
标头。
我确认 Amir 是正确的 (Django 1.11.8),它允许使用 self.assertRedirects
(或 status_code
)检查重定向并检查重定向位置。【参考方案5】:
您可以使用 assertRedirects 例如:
response = self.client.get('/sekrit/')
self.assertRedirects(response, '/other/login/?next=/sekrit/')
https://docs.djangoproject.com/en/2.0/topics/testing/tools/#django.test.SimpleTestCase.assertRedirects
如果你需要获取重定向的url
如果follow
是True
你会得到网址
response.redirect_chain[-1]
如果follow
是False
response.url
【讨论】:
以上是关于Django:测试页面是不是已重定向到所需的 url的主要内容,如果未能解决你的问题,请参考以下文章
Laravel - 用户未通过身份验证时如何重定向到所需页面