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

Dee*_*eyi 57 python django django-testing

在我的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
Run Code Online (Sandbox Code Playgroud)

我该如何写测试?这就是我到目前为止:

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/')
Run Code Online (Sandbox Code Playgroud)

接下来会发生什么?

imp*_*ren 110

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和status代码.

如果fetch_redirect_responseFalse,则不会加载最终页面.由于测试客户端无法获取外部URL,因此如果expected_url不是Django应用程序的一部分,则此功能特别有用.

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


ign*_*low 49

你也可以按照重定向:

response = self.client.get('/myprofile/data/some_id/', follow=True)
Run Code Online (Sandbox Code Playgroud)

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

self.assertContains(response, "You must be logged in", status_code=401)
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的'follow = True`. (17认同)
  • 在测试中期望特定的页面内容是危险的。使得非程序员(网页编辑者)有可能在不知不觉中破坏测试。 (2认同)

luc*_*luc 25

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

  • 当人们不关心`target_status_code`将是什么时最好. (3认同)

Ala*_*ars 10

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)
Run Code Online (Sandbox Code Playgroud)

  • 如果未提供"follow = True",则**可用.Django(任何版本)都不会删除像"Location"这样的正常响应头.当`follow`为'True`时,将遵循重定向,自然最后一个响应没有`Location`标题. (5认同)