SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

モダンDjango入門

Djangoのテストの書き方とCircleCIを活用した継続的インテグレーション

モダンDjango入門 第3回

  • このエントリーをはてなブックマークに追加

 日本でカンファレンスも開催されて、ますます盛り上がりを見せているDjango。この連載では最新のDjangoとDjango REST frameworkを用いたプロダクト開発の手法を、実務に使える形でお伝えしていきます。今回はまずDjangoの実践的なテストの書き方と、CircleCIを使った継続的インテグレーションを紹介します。

  • このエントリーをはてなブックマークに追加

今回の内容

 前回はDjango 2.0での変更点を取り上げ、モデルの定義、Django REST frameworkの導入ついて解説しました。前回までのコードは以下から取得できます。

 第3回となる今回は、まず前回実装したViewに対するテストを取り上げます。Djangoの標準的なテストから始めて、サードパーティを利用したより実践的なテストの書き方を紹介します。その次に、実装したテストをCircleCIでの継続的インテグレーションに組み込みます。

テストの作成

 前回Django REST frameworkのModelViewSetを用いて実装したkanban/board/views.pyの品質を担保するために、テストを書いてみましょう。

 python manage.py startappを実行した際にtests.pyというテスト用のファイルが作成されているので、まずはそこにテストを書いていきます。

TestCase

 DjangoではPython標準のunittest.TestCaseを拡張したものであるdjango.test.TestCaseが用意されています。次の図は、unittestとDjangoの各TestCase間の継承関係を表したものです。

unittestとDjangoの各TestCase間の継承関係
unittestとDjangoの各TestCase間の継承関係

 django.test.TestCaseには、Djangoアプリケーションのテストを書くうえで役立つ機能が以下のように数多く備わっています。

  • フィクスチャ読み込みによるテストデータ生成
  • settingsの上書き機能
  • 独自のアサーションメソッド
  • タギングによるテストの分類
  • メール送信をダミーの送信箱に振り分け
  • 各テストを実行する度にDBをロールバック

 それでは、データをPOSTしてチケットが正常に作成されるかを確かめるテストを書いてみます。

import json

from django.test import TestCase
from django.urls import reverse
from rest_framework import status

from kanban.board.models import Ticket


class TicketTests(TestCase):

    def test_post(self):
        url = reverse('ticket-list')
        data = {
            'assignee': None,
            'name': 'test ticket',
            'description': 'This is a test ticket.',
            'status': 1,
            'start': '2018-06-01',
            'end': None,
        }
        response = self.client.post(url, json.dumps(data), content_type='application/json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(Ticket.objects.count(), 1)
        self.assertEqual(Ticket.objects.get().name, 'test ticket')

 django.test.TestCaseself.clientはデフォルトで、django.test.Clientのインスタンスが格納されています。django.test.Clientとは、ダミーのブラウザのように振る舞い、DjangoのHTTP関連のテストを助けるものです。

 self.client.post(url, json.dumps(data), 'application/json')とすることで、http://localhost:8000/api/tickets/に向けて、以下のJSONをPOSTできます。

{
    "assignee": null,
    "name": "test ticket",
    "description": "This is a test ticket.",
    "status": 1,
    "start": "2018-06-01",
    "end": null
}

 self.assertEqual()を使って、以下の観点から期待した値かどうかをチェックしています。

  • ステータスコードが201かどうか
  • 作成されたレコードが1つかどうか
  • 作成されたチケットのname属性が正しいかどうか

 ここでは1つのテストケースに複数のassertを実行していますが、途中のアサーションで失敗するとそれ以降のアサーションは実行されません。この方式とは別に、テストケース毎に1つのアサーション(one assertion per test)で実装するやり方もあります。この方式の利点は、どのデータが原因でテストが失敗しているのかわかりやすくなる点や、どのテストケースが落ちているかを正しくレポートできる点にあります。

 テストの実行には、python manage.py test <ラベル名>コマンドを使います。

(env) $ python manage.py test kanban
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.066s

OK

 python manage.py testの引数には、Pythonのモジュールなどを指定するようになっています。以下のようにテストケースやテストメソッドを指定することで、実行したいテストの範囲を絞ることも可能です。今のところテストメソッドは1つしか実装していないため、以下の4つはすべて同じ振る舞いになります。

  • python manage.py test kanban
  • python manage.py test kanban.board
  • python manage.py test kanban.board.tests.TicketTests
  • python manage.py test kanban.board.tests.TicketTests.test_post

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
Faker

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
モダンDjango入門連載記事一覧

もっと読む

この記事の著者

新井 正貴(アライ マサタカ)

 東京大学文学部卒業、アライドアーキテクツ株式会社にて勤務。2016年4月、株式会社SQUEEZEに入社。コミュニティ活動として、PyCon JP 2015〜 スタッフ、Pythonもくもく会の主催を行う。趣味はラクロスとPerfume。 Site:http://massa142.github.io/ Twitter:@massa142 Facebook:新井 正貴

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10995 2018/08/03 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング