Refactoring My Intelligence

技術的/非技術的な雑記,備忘録等々

Django1.5 tutorial Part5 個人的メモ

自動テストの紹介

自動化テストとは

テスト作成は何故必要か

テスティングの基本戦略

ここまでは省略.この辺の話はテスト駆動開発とかのキーワードでWeb検索するか書籍等で勉強すればよい.

最初のテストを書く

Polls.was_published_recently()にバグがあるのでそれを直す.

バグを暴くためのテストを作る

polls/tests.pyの内容を以下のようにする.

import datetime

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

from polls.models import Poll

class PollMethodTests(TestCase):

    def test_was_published_recently_with_future_poll(self):
        """
        was_published_recently() should return False for polls whose
        pub_date is in the future
        """
        future_poll = Poll(pub_date=timezone.now() + datetime.timedelta(days=30))
        self.assertEqual(future_poll.was_published_recently(), False)

テストを走らせる

以下のコマンドを端末で実行するとテストが走る.

python manage.py test polls
Creating test database for alias 'default'...
F
======================================================================
FAIL: test_was_published_recently_with_future_poll (polls.tests.PollMethodTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/hikida.satoshi/study/django/ENV/projects/mysite/polls/tests.py", line 12, in test_was_published_recently_with_future_poll
    self.assertEqual(future_poll.was_published_recently(), False)
AssertionError: True != False

----------------------------------------------------------------------
Ran 1 test in 0.016s

FAILED (failures=1)
Destroying test database for alias 'default'...

結果はこんな感じ.アサーションエラーとなっているのが分かる.

バグを直す

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

で,テストを実行すると

Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Destroying test database for alias 'default'...

こんな感じになる.

より包括的なテスト

was_published_recently()メソッドをより包括的にテストするように以下のテストコードをさらに追加する.

def test_was_published_recently_with_old_poll(self):
    """
    was_published_recently() should return False for polls whose pub_date
    is older than 1 day
    """
    old_poll = Poll(pub_date=timezone.now() - datetime.timedelta(days=30))
    self.assertEqual(old_poll.was_published_recently(), False)

def test_was_published_recently_with_recent_poll(self):
    """
    was_published_recently() should return True for polls whose pub_date
    is within the last day
    """
    recent_poll = Poll(pub_date=timezone.now() - datetime.timedelta(hours=1))
    self.assertEqual(recent_poll.was_published_recently(), True)

Viewのテスト

clientテスト

Djangoはviewレベルにおけるユーザーとの対話をシミュレートするClientテストを提供している. んだけどコード写したり翻訳するのもう面倒くさいので以下略.