Djangoにはアプリケーションのバグチェックを自動でおこなうための自動テストという機能を使うことができる。

今回は、これまでのチュートリアルで作成してきたPollsアプリに自動テストを導入する手順を紹介する。

バグの確認

polls/models.pyに定義されているQuestion.was_published_recently()メソッドを見てみよう。

def was_published_recently(self):
	return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

これは質問が昨日以降に公開されている場合にTrueを返すメソッドだが一つ問題がある。

公開日が未来の日付になっていた場合にもTrueが返されてしまうのだ。

今回はこの問題を自動テストを使って確認し、問題を解決していく。

テストの作成

テストはpolls/tests.pyに書いていく。

import datetime

from django.test import TestCase
from django.utils import timezone

from .models import Question

class QuestionModelTests(TestCase):
	def test_was_published_recently_with_future_question(self):
		time = timezone.now() + datetime.timedelta(days=30)
		future_question = Question(pub_date=time)
		self.assertIs(future_question.was_published_recently(), False)

django.test.TestCaseを継承するQuestionModelTestsクラスを作成した。

test_was_published_recently_with_future_question()メソッドでは、まず30日後の日付を公開日としたQuestionオブジェクトを用意する。

次にassertIs()メソッドを実行するが、これは第一引数に検証したいメソッドを渡し、第二引数に期待値を指定する。

今回の場合、未来の公開日が設定されたfuture_questionのwas_published_recently()メソッドを渡し、返り値が期待する結果であるFalseでなかった場合、テストの結果としてエラーが出力される。

テストの実行

テストファイルが作成できたら、いよいよ自動テストを実行してみる。

python manage.py test polls

上記のコマンドをターミナルで実行すると、先ほど定義したバグチェックが走り、エラーの原因となったファイルとコードの箇所が出力されるはずだ。

バグを修正する

問題はpolls/models.pyのQuestionクラス、was_published_recently()メソッドにある。

コードを以下のように修正しよう。

def was_published_recently(self):
	now = timezone.now()
	return now - datetime.timedelta(days=1) <= self.pub_date <= now

これで公開日が未来の日付だった場合、Falseが返されるようになった。

再度テストを実行し、エラーが出力されなければOKだ。