web-dev-qa-db-ja.com

Django:ページが目的のURLにリダイレクトされたかどうかをテストする

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/')

次に何が来るのでしょうか?

57

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_responseFalseの場合、最終ページは読み込まれません。テストクライアントは外部URLを取得できないため、expected_urlがDjango =アプリ。

2つのURLを比較するとき、スキームは正しく処理されます。リダイレクト先にスキームが指定されていない場合、元のリクエストのスキームが使用されます。存在する場合、expected_urlのスキームは、比較を行うために使用されるスキームです。

110
imposeren

次の方法でリダイレクトを追跡することもできます。

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

これにより、ブラウザでのユーザーエクスペリエンスが反映され、そこにあると思われるものを次のように表明できます。

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

response['Location']を確認し、予想されるURLと一致するかどうかを確認できます。ステータスコードが302であることも確認してください。

26
luc

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)
10
Alan Viars