Django:テストの壁を乗り越えろ!test.Response.status_codeを使いこなして自信のつくテストコードを書く


django.test モジュールは、Django アプリケーションのテストを容易にするためのツールを提供します。その中でも、test.Response.status_code 属性は、HTTP レスポンスのステータスコードを確認するために使用されます。

詳細

test.Response.status_code は、HTTP レスポンスのステータスコードを表す整数値です。この値は、リクエストが成功したか失敗したかを判断するために使用されます。

from django.test import Client

def test_index_view(self):
    c = Client()
    response = c.get('/')
    self.assertEqual(response.status_code, 200)

上記の例では、/ パスへの GET リクエストが成功し、ステータスコード 200 が返されることをテストしています。

以下は、一般的な HTTP ステータスコードとその意味です。

  • 500: 内部サーバーエラー
  • 404: ページが見つかりません
  • 401: 認証エラー
  • 400: 不正なリクエスト
  • 200: 成功

テストにおける活用

test.Response.status_code は、以下の目的で使用できます。

  • リダイレクトが正しく行われていることを確認する
  • エラー処理が適切に機能していることを確認する
  • ビューが正しいステータスコードを返していることを確認する


特定のステータスコードが返されることを確認する

from django.test import Client

def test_login_view(self):
    c = Client()
    response = c.post('/login/', {'username': 'john', 'password': 'doe'})
    self.assertEqual(response.status_code, 200)

エラー処理を検証する

from django.test import Client

def test_protected_view(self):
    c = Client()
    response = c.get('/protected/')
    self.assertEqual(response.status_code, 403)

この例では、/protected/ パスへの GET リクエストが失敗し、ステータスコード 403 が返されることをテストしています。これは、保護されたビューへのアクセスが適切に制限されていることを確認します。

from django.test import Client

def test_redirect_view(self):
    c = Client()
    response = c.get('/old_url/')
    self.assertEqual(response.status_code, 302)
    self.assertEqual(response.url, '/new_url/')

この例では、/old_url/ パスへの GET リクエストがリダイレクトされ、ステータスコード 302 と新しい URL /new_url/ が返されることをテストしています。これは、URL の変更が適切に処理されていることを確認します。

これらの例は、test.Response.status_code 属性を使用して、さまざまなテストケースを記述する方法を示しています。実際のテストケースでは、具体的な状況に合わせてコードを調整する必要があります。

  • テストコードは、簡潔で読みやすく、理解しやすいように記述することが重要です。コメントを使用して、テストケースの目的を説明することが有効です。
  • テストコードを書く際は、できるだけ具体的なアサーションを使用することが重要です。例えば、単に self.assertEqual(response.status_code, 200) とするのではなく、self.assertEqual(response.status_code, HTTP_STATUS_OK) と書くようにします。


代替方法の例

以下に、test.Response.status_code の代替方法の例をいくつか紹介します。

  • self.assertEqual(response.status_code, expected_status_code) の代わりに、self.assertContains(response, expected_status_text) を使用します。これは、レスポンスの本文に特定のステータスコードのテキストが含まれていることを確認します。
from django.test import Client

def test_login_view(self):
    c = Client()
    response = c.post('/login/', {'username': 'john', 'password': 'doe'})
    self.assertContains(response, 'HTTP/1.1 200 OK')
  • self.assertEqual(response.status_code, expected_status_code) の代わりに、self.assertRaises(expected_exception) を使用します。これは、特定の例外がスローされることを確認します。
from django.test import Client

def test_protected_view(self):
    c = Client()
    with self.assertRaises(PermissionDenied):
        c.get('/protected/')

それぞれの方法の利点と欠点

方法利点欠点
self.assertEqual(response.status_code, expected_status_code)シンプルでわかりやすいステータスコードの詳細な情報が得られない
self.assertContains(response, expected_status_text)ステータスコードの詳細な情報が得られる本文にステータスコードのテキストが含まれていない場合、テストが失敗する
self.assertRaises(expected_exception)例外がスローされることを確認できるテスト対象のコードが実際に例外をスローする必要がある

具体的な状況

上記で紹介した代替方法は、それぞれ異なる状況で役立ちます。

  • シンプルでわかりやすいテストコードを書きたい場合 は、self.assertEqual(response.status_code, expected_status_code) を使用するのが適切です。
  • 特定の例外がスローされることを確認したい場合 は、self.assertRaises(expected_exception) を使用するのが適切です。
  • レスポンスの本文にステータスコードの情報が含まれている場合 は、self.assertContains(response, expected_status_text) を使用するのが適切です。