IT Log

Django Tutorial 05 본문

Open Source/Django

Django Tutorial 05

newly0513 2020. 7. 26. 12:22
728x90
반응형

1. 첫번째 Test 작성하기

1-1. 버그 식별하기

Terminal

python manage.py shell

# shell에 접속되고나서 실행
import datetime
from django.utils import timezone
from polls.models import Question
future_question = Question(pub_date=timezone.now() + datetime.timedelta(days=30))
future_question.was_published_recently()

해당 테스트는 미래의 날짜는 없기 때문에 False가 나와야하는데 True가 나왔으므로 False가 나오도록 수정해줍니다.


1-2. 버그 발생시키기

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):
        """
        was_published_recently() returns False for questions whose pub_date
        is in the future.
        """
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(pub_date=time)
        self.assertIs(future_question.was_published_recently(), False)


1-3. Test 실행

Terminal

python manage.py test polls

was_published_recently()가 False를 반환해야되는데 True를 반환해서 생기는 오류로 그렇지 않게 수정해야합니다.


1-4. 버그 수정

polls/models.py

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

 

Terminal

python manage.py test polls

문제없이 Test를 마친 것을 확인할 수 있습니다.


1-5. 좀더 포괄적인 Test

polls/tests.py

def test_was_published_recently_with_old_question(self):
    """
    was_published_recently() returns False for questions whose pub_date
    is older than 1 day.
    """
    time = timezone.now() - datetime.timedelta(days=1, seconds=1)
    old_question = Question(pub_date=time)
    self.assertIs(old_question.was_published_recently(), False)

def test_was_published_recently_with_recent_question(self):
    """
    was_published_recently() returns True for questions whose pub_date
    is within the last day.
    """
    time = timezone.now() - datetime.timedelta(hours=23, minutes=59, seconds=59)
    recent_question = Question(pub_date=time)
    self.assertIs(recent_question.was_published_recently(), True)

과거, 최근, 미래의 질문에 대해 올바른 값을 반환한다는 걸 확인하는 총 3가지의 포괄적인 Test를 가졌습니다.


2. View Test

2-1. Django Test Client

Terminal

python manage.py shell

from django.test.utils import setup_test_environment
setup_test_environment()
from django.test import Client
client = Client()
response = client.get('/')
response.status_code
from django.urls import reverse
response = client.get(reverse('polls:index'))
response.status_code
response.content
response.context['latest_question_list']


2-2. View 개선시키기

polls/views.py

#추가
from django.utils import timezone

# 해당 부분만 수정
def get_queryset(self):
    """
    Return the last five published questions (not including those set to be
    published in the future).
    """
    return Question.objects.filter(
        pub_date__lte=timezone.now()
    ).order_by('-pub_date')[:5]

Question.objects.filter (pub_date__lte = timezone.now ()) timezone.now보다 pub_date가 작거나 같은 Question을 포함하는 queryset을 반환합니다.


2-3. 새로운 View Test

polls/tests.py

from django.urls import reverse

def create_question(question_text, days):
    """
    Create a question with the given `question_text` and published the
    given number of `days` offset to now (negative for questions published
    in the past, positive for questions that have yet to be published).
    """
    time = timezone.now() + datetime.timedelta(days=days)
    return Question.objects.create(question_text=question_text, pub_date=time)


class QuestionIndexViewTests(TestCase):
    def test_no_questions(self):
        """
        If no questions exist, an appropriate message is displayed.
        """
        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context['latest_question_list'], [])

    def test_past_question(self):
        """
        Questions with a pub_date in the past are displayed on the
        index page.
        """
        create_question(question_text="Past question.", days=-30)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ['<Question: Past question.>']
        )

    def test_future_question(self):
        """
        Questions with a pub_date in the future aren't displayed on
        the index page.
        """
        create_question(question_text="Future question.", days=30)
        response = self.client.get(reverse('polls:index'))
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context['latest_question_list'], [])

    def test_future_question_and_past_question(self):
        """
        Even if both past and future questions exist, only past questions
        are displayed.
        """
        create_question(question_text="Past question.", days=-30)
        create_question(question_text="Future question.", days=30)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ['<Question: Past question.>']
        )

    def test_two_past_questions(self):
        """
        The questions index page may display multiple questions.
        """
        create_question(question_text="Past question 1.", days=-30)
        create_question(question_text="Past question 2.", days=-5)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ['<Question: Past question 2.>', '<Question: Past question 1.>']
        )


2-4. Detail View Test

polls/views.py

class DetailView(generic.DetailView):
    ...
    def get_queryset(self):
        """
        Excludes any questions that aren't published yet.
        """
        return Question.objects.filter(pub_date__lte=timezone.now())

 

polls/tests.py

class QuestionDetailViewTests(TestCase):
    def test_future_question(self):
        """
        The detail view of a question with a pub_date in the future
        returns a 404 not found.
        """
        future_question = create_question(question_text='Future question.', days=5)
        url = reverse('polls:detail', args=(future_question.id,))
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

    def test_past_question(self):
        """
        The detail view of a question with a pub_date in the past
        displays the question's text.
        """
        past_question = create_question(question_text='Past Question.', days=-5)
        url = reverse('polls:detail', args=(past_question.id,))
        response = self.client.get(url)
        self.assertContains(response, past_question.question_text)


2-5. Web에서 확인해보기

현재 등록된 질문은 What'up? 하나이고, 새로운 질문을 등록했을 때 등록된 질문의 시간이 현재보다 미래의 시간으로 등록하면 화면에서 나타나지 않도록 위의 코드들을 수정해 왔습니다. 그 부분을 확인하도록 하겠습니다. 

 

좌 - polls 질문 목록 / 우 - admin사이트 상황

admin 사이트에서 현재 시간보다 좀 더 미래의 시간으로 질문을 등록해보겠습니다.


ADD QUESTION을 클릭합니다 그러면 우측화면 Question text를 작성하고 Today와 Now를 눌러 시간을 설정한 뒤 시간에서 현재보다 나중 시간으로 수정하고 SAVE합니다.


그러면 admin사이트에서는 분명 질문을 추가했는데 질문목록에서는 추가한 질문이 보이질 않습니다. 그렇다면 새로 등록한 질문의 시간을 현재시간과 동일하게 수정해보겠습니다.


등록했던 질문을 클릭합니다. 그런 다음 시간에서 Now를 클릭해서 현재 시간으로 맞춰준 뒤 SAVE를 클릭합니다.


추가한 질문이 질문목록에서 보이는 것을 확인할 수 있습니다.

728x90
반응형

'Open Source > Django' 카테고리의 다른 글

Django Tutorial 04  (0) 2020.07.25
Django Tutorial 03  (0) 2020.07.21
Django Tutorial 02  (0) 2020.07.19
Django Tutorial 01  (0) 2020.07.19
Comments