[백엔드/Django] - [Django] Document 따라 읽기(6) - Model 테스트
[Django] Document 따라 읽기(6) - Model 테스트
[백엔드/Django] - [Django] Document 따라 읽기(5) - 앱 작성(2) [Django] Document 따라 읽기(5) - 앱 작성(2) [전체 보기] - [Django] Document 따라 읽기(4) - 앱 작성(1) [Django] Document 따라 읽기(4) - 앱 작성(1) [백엔드/Dj
dog-foot-writen.tistory.com
두 번째 테스트
Django에서는 View 레벨에서 코드와 상호작용 하는 사용자 시뮬레이션 Test를 제공합니다.
get 등의 함수를 통해 어플리케이션을 제어할 수 있습니다.
python manage.py shell
from django.test.utils import setup_test_environment
setup_test_environment()
from django.test import Client
client = Client()
# 저희는 / 경로에 아무것도 지정하지 않았기 때문에 404로 return됩니다.
response = client.get("/")
response.status_code
# 404
# reverse 함수는 polls 에서 index를 찾아 url 을 반환합니다.
from django.urls import reverse
response = client.get(reverse("polls:index"))
response.status_code
# 200
View 개선
현재 polls 애플리케이션에서는 pub_date가 오지 않은 여론조사 또한 출력됩니다. 하지만 pub_date가 미래의 날짜라면 화면에는 나오지 말아야 하기 때문에 해당 부분을 수정하도록 하겠습니다.
# polls/views.py
from django.utils import timezone
class IndexView(generic.ListView):
...생략...
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_dat")[:5]
Question.objects.filter(pub_date__lte= timezone.now()) 는 timezone.now() 보다 이전 값을 반환합니다.
filter 메서드의 많은 사용 방법은 공식 Document로 대체 하겠습니다.
새로운 View 테스트
이제 Question에 과거, 미래의 날짜가 포함된 질문을 만들고, pub_date로 제대로 항목들이 나열되는지 확인해야 합니다.
저희는 첫 번째 테스트와 같은 테스트 코드를 작성하겠습니다.
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):
# question이 없는지 체크합니다.
# "No polls are available" 메세지와 latest_question_list가 비어있는지 체크합니다.
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"], [])
# create_question 함수를 통해 pub_date가 과거인 question을 생성합니다.
# 이후 polls의 index 페이지로 넘어간뒤 latest_question_list에 question이 존재하는지 체크합니다.
def test_past_question(self):
"""
Questions with a pub_date in the past are displayed on the
index page.
"""
question = create_question(question_text="Past question.", days=-30)
response = self.client.get(reverse("polls:index"))
self.assertQuerySetEqual(
response.context["latest_question_list"],
[question],
)
# create_question 함수를 통해 pub_date가 미래인 question을 생성합니다.
# 이후 polls의 index 페이지로 넘어간뒤 latest_question_list에 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"], [])
# test_past_question(), test_future_question()을 합친 테스트 코드입니다.
def test_future_question_and_past_question(self):
"""
Even if both past and future questions exist, only past questions
are displayed.
"""
question = 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],
)
# question을 여러개 넣은 경우를 테스트 합니다.
def test_two_past_questions(self):
"""
The questions index page may display multiple questions.
"""
question1 = create_question(question_text="Past question 1.", days=-30)
question2 = create_question(question_text="Past question 2.", days=-5)
response = self.client.get(reverse("polls:index"))
self.assertQuerySetEqual(
response.context["latest_question_list"],
[question2, question1],
)
DetailView 테스트
만약 질문이 index페이지에 표시되지 않더라도 올바른 URL을 알고있거나 추측하여 들어온다면 해당 질문에 접근할 수 있게됩니다. 따라서 다음과 같은 제약 조건을 추가하겠습니다.
# 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())
이후 Question의 pub_date가 과거인 값이 표시되어지는지, 미래인 값이 표시되어지는지에 대한 테스트 코드를 작성합니다.
# 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)
'백엔드 > Django' 카테고리의 다른 글
[Django] Document 따라 읽기(6) - Model 테스트 (0) | 2023.11.14 |
---|---|
[Django] Document 따라 읽기(5) - 앱 작성(2) (0) | 2023.11.10 |
[Django] Document 따라 읽기(3) - admin 페이지 (0) | 2023.11.06 |
[Django] Document 따라 읽기(1) - Tutorial(설치, 데이터베이스 연결) (0) | 2023.11.04 |
[Django] Documnet 따라 읽기(2) - View, Model, CRUD API(1) (1) | 2023.11.03 |
[Django] Django(장고)란? (0) | 2023.10.27 |