Djangoのテスト


はじめに

ここでは、Djangoにおけるテストについて解説していきます。

テスト対象

テスト対象は、以下のシンプルなブログ記事一覧ページとします。

project/urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')
]
blog/urls.py
from django.urls import path

from . import views

app_name = 'blog'
urlpatterns = [
    path('list/', views.PostList.as_view(), name='post_list')
]
blog/models.py
from django.db import models


class Post(models.model):
    title = models.CharField('タイトル', max_length=100)
    body = models.TextField('本文')
    created_at = models.DateTimeField('作成日時', auto_now_add=True)
    updated_at = models.DateTimeField('更新日時', auto_now=True)

    class Meta:
        ordering = ('-created_at')

    def __str__(self):
        return self.title
blog/views.py
from django.views import generic


class PostList(generic.ListView):
    model = Post
    template_name = 'blog/post_list.html'
blog/post_list.html
{% for post in post_list %}
<h1>{{ post.title }}</h1>
<p>{{ post.body }}</p>
{% endfor %}

ファクトリークラスの作成

factory_boyを使うと、テスト用のレコードを作成することができます。

blog/tests.py
import factory
from django.utils import timezone

from .models import Post


class PostFactory(factory.django.DjangoModelFactory):
    title = 'Sample post'
    body = 'This is a sample text.'
    created_at = timezone.now()
    updated_at = timezone.now()

    class Meta:
        model = Post

ここでは、Postモデル用のファクトリークラスとして、PostFactoryを作成します。
titletextなどのデフォルト値を設定できます。

テストの作成

blog/tests.py
from django.urls import reverse
from django.test import TestCase


class PostListTests(TestCase):

    def test_get_queryset(self):
        post_1 = PostFactory(
            title='First Post',
            body='This is the first post.'
        )
        post_2 = PostFactory(
            title='Second Post',
            body='This is the second post.'
        )
        res = self.client.get(reverse('blog:post_list'))
        self.assertTemplateUsed(res, 'blog/post_list.html')
        self.assertQuerysetEqual(
            res.context['post_list'],
            ['<Post: Second Post>', '<Post: First Post>']
        )
        self.assertEqual(
            res.context['post_list'][0].body,
            'This is the first post.'
        )
        self.assertEqual(
            res.context['post_list'][1].body,
            'This is the second post.'
        )

まず、上で作成したPostFactoryを用いて、Postのレコードを作成します。
そして、記事一覧ページにアクセスした時のレスポンスを変数resに格納します。
resには、viewで作成されるcontextとしてpost_listが含まれますので、期待通りのquerysetが得られているかを確認します。
また、djangoのテストでは、views.pyで指定したHTMLテンプレートが使用されているかを確認するために、assertTemplateUsedが使えます。

テストの実行

テストを実行するには、以下のコマンドを入力します。

$ python manage.py test (blog)

最後にアプリケーション名を入れると、指定したアプリケーションでのみテストが実行されます。

まとめ

ここでは、djangoにおけるテストについて解説しました。
開発が進む中でバグを防止するためにもテストは重要です。