Django:测试页面是否已重定向到所需的URL


73

在我的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/')

接下来可能会发生什么?

Answers:


126

Django 1.4:

https://docs.djangoproject.com/zh-CN/1.4/topics/testing/#django.test.TestCase.assertRedirects

Django 2.0:

https://docs.djangoproject.com/zh-CN/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

如果您的请求中使用的跟踪参数,expected_urltarget_status_code将是重定向链的最终点的网址和状态代码。

如果fetch_redirect_responseFalse,则不会加载最后一页。由于测试客户端无法获取外部URL,因此如果Expected_url不属于Django应用,则这特别有用。

在两个URL之间进行比较时,可以正确处理方案。如果在我们重定向到的位置中未指定任何方案,则使用原始请求的方案。如果存在,expected_url中的方案就是用来进行比较的方案。


56

您还可以通过以下方式进行重定向:

response = self.client.get('/myprofile/data/some_id/', follow=True)

这将反映浏览器中的用户体验,并断言您希望在浏览器中找到的内容,例如:

self.assertContains(response, "You must be logged in", status_code=401)

1
在测试中期望特定页面内容是危险的。使非程序员(网页编辑器)可能在不知不觉中破坏测试。
2014年

31

您可以检查response['Location']它是否与预期的网址匹配。还要检查状态码是302。


3
最适合不关心target_status_code会发生什么的情况。
emyller

直接在视图上进行单元测试时(不使用Django客户端),这是正确的答案。
亚伦D

12

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)

8
如果未提供,可用follow=True。Django(任何版本)都不会删除常规响应标头,例如Location。当follow为时True,将遵循重定向,自然而然的是最后一个响应没有Location头。
阿米尔·阿里·阿克巴里

我确认Amir是正确的(Django 1.11.8),它允许使用self.assertRedirects(或status_code)检查重定向并检查重定向位置。
拉菲
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.