갈루아의 반서재

We identify a bug

Question.was_published_recently() 모듈은 설문 생성일이 도래하지 않은 미래인 경우에도 T 값을 반환하고 있다.

 

Admin 페이지에서 설문생성일이 미래임에도 최근에 생성된 질문에 체크되어 있음을 아래와 같이 확인할 수 있다.

 

 

 

셀을 통해서도 위의 내용은 확인가능하다. 

 

>>> import datetime
>>> from django.utils import timezone
>>> from polls.models import Question
>>> # create a Question instance with pub_date 30 days in the future
>>> future_question = Question(pub_date=timezone.now() + datetime.timedelta(days=30))
>>> # was it published recently?
>>> future_question.was_published_recently()
True


미래의 질문은 '최신'에 속하지 않으므로 분명 위의 응답은 잘못된 것이다.



Create a test to expose the bug


이제 아래와 같은 tests.py 파일을 만들자.


polls/tests.py

import datetime

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

from .models import Question


class QuestionMethodTests(TestCase):

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


우리는 여기서 미래의 pub_date 를 가지는 Question 인스턴스를 생성하는 메서드를 가진 django.test.TestCase 라는 서브클래스를 생성했다. 그리고 

was_published_recently() 의 결과물이 False 로 나오는지 체크할 것이다. 

 


Running tests


그럼 터미널에서 아래와 같이 테스트를 해보자.


$ python manage.py test polls


그러면 다음과 같은 결과를 보게 될 것이다.


Creating test database for alias 'default'...

F

======================================================================

FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionMethodTests)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "/path/to/mysite/polls/tests.py", line 16, in test_was_published_recently_with_future_question

    self.assertEqual(future_question.was_published_recently(), False)

AssertionError: True != False


----------------------------------------------------------------------

Ran 1 test in 0.001s


FAILED (failures=1)

Destroying test database for alias 'default'...



다음과 같이 위의 테스트는 진행된다.


1. python manage.py test polls 를 통해 polls 어플리케이션의 test 검색

2. django.test.TestCase 클래스라는 서브클래스 발견

3. 테스트를 위한 default 데이터베이스 생성

4. test_was_published_recently_with_future_question 라는 이름으로 시작되는 테스트 메서드 검색

5. False 를 반환해야함에도 assertEqual() 메서드를 통해 was_published_recently() 가 True 값을 반환함을 확인

6. 해당 테스트가 실패했음을 최종 확인



Fixing the bug


이번 예제에서는 우리는 이미 문제가 무엇인지를 알고 있다.

pub_date 가 미래의 날짜라면 Question.was_published_recently() 는 False 값을 반환해야한다. models.py 파일을 수정해보자. 


polls/models.py

[수정전]

def was_published_recently(self):

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

   

[수정후]

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'...







[수정전]

미래에 생성된 설문이 최근 설문으로 표시됨



[수정후]