[Django] 06.자동화된 테스트
첫 번째 장고 앱작성하기, part 5
- 애플리케이션을 구축했으면 자동화 테스트를 작성
테스트가 필요한 이유
- 특정 모델 메소드에서 예상된 값을 반환하는지
- 사이트에서 사용자의 입력 시퀀스가 원하는 결과를 생성하는지
- 등등..
버그 테스트 케이스 만들기
- polls/tests.py
import datetime
from django.utils import timezone
from django.test import TestCase
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)
테스트 실행
python manage.py test polls
버그 수정
- polls/models.py
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
포괄적인 테스트
- waspublishedrecently()메소드를 고정하게 되면, 다른 버그를 하나 고치면 새로운 버그가 생길 수 있기 때문에 메소드의 동작을 보다 포괄적으로 테스트하기 위해 동이한 클래스에 두가지 테스트 메소드를 추가
- 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)
클라이언트 테스트
- django는 뷰레벨에서 코드와 상호작용하는 사용자를 시뮬레이트하기위해 테스트 클라이언트 클래스 Client를 제공한다.
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']
뷰를 개선시키기
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]
새로운 뷰 테스트
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.>']
)
참고
'Python > Django' 카테고리의 다른 글
[Django]Python 가상환경 만들기 / Django 설치 (0) | 2021.11.26 |
---|---|
[Django] 각종 유용한 패키지 (0) | 2021.04.29 |
[Django] 08.관리자 폼 커스터마이징 (0) | 2021.04.29 |
[Django] 07.스타일시트와 이미지 추가 (0) | 2021.04.29 |
[Django] 05.간단한 폼처리와 소스코드 줄이기 (0) | 2021.04.29 |
[Django] 04. 어플리케이션 View 만들기 (0) | 2021.04.29 |
[Django] 03.데이터베이스 연동하기(migration, model 생성) (0) | 2021.04.29 |
[Django] 02.프로젝트 만들기 및 시작하기 (간단한 설문조사 어플리케이션 만들기) (0) | 2021.04.29 |