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

82

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

接下来可能会发生什么?

5个回答

136

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_urltarget_status_code 将是重定向链的最终点的 URL 和状态码。

如果 fetch_redirect_responseFalse,则最终页面不会被加载。由于测试客户端无法提取外部 URL,因此如果 expected_url 不属于您的 Django 应用程序,则此选项特别有用。

在比较两个 URL 时正确处理协议。如果重定向到的位置中没有指定任何协议,则使用原始请求的协议。如果存在,则使用 expected_url 中的协议进行比较。


60

你也可以使用以下方式跟随重定向:

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

这将反映用户在浏览器中的体验,并作出您期望在其中找到的断言,例如:

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

2
在测试中期望特定页面内容是危险的。这可能会导致非程序员(网页编辑人员)无意中破坏测试。 - aliteralmind

37

您可以检查response['Location']并查看其是否与期望的URL匹配。还要检查状态代码是否为302。


3
最适用于不关心target_status_code将是什么的情况。 - emyller
在直接对视图进行单元测试时(不使用Django客户端),这是正确的答案。 - Aaron D

16

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)

9
如果没有提供follow=True,则可以获得它。 Django(任何版本)不会删除正常的响应头,如Location。当followTrue时,将跟随重定向,并且最后一个响应自然没有Location头。 - Amir Ali Akbari
我确认Amir是正确的(Django 1.11.8),它允许使用self.assertRedirects(或status_code)检查重定向并检查重定向位置。 - Raffi

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接