일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- k-eta
- 매크로
- Django Nodejs 차이점
- vscode
- getline
- iOS14
- 장고란
- Django란
- 구조체와 클래스의 공통점 및 차이점
- EOF
- 2557
- 입출력 패턴
- 표준 입출력
- 연결요소
- c++
- string 함수
- correlation coefficient
- Django의 편의성
- 알고리즘 공부방법
- double ended queue
- 엑셀
- 프레임워크와 라이브러리의 차이
- 이분그래프
- UI한글변경
- 자료구조
- string 메소드
- 입/출력
- 백준
- 시간복잡도
- scanf
- Today
- Total
Storage Gonie
35. (app2) view 및 템플릿 테스트하기 본문
***python manage.py test polls 명령어로 테스트를 실행하면 메소드별로 테스트 비어있는 DB가 생성되며 이는 실행종료시 같이 삭제된다. 따라서 각 메소드는 서로 영향을 받지 않는다.***
1. 테스트 전, 쉘에서 확인한 뒤 실제 코드를 작성할 것임.(쉘에서는 따로 비어있는 DB가 생성되는게 아니란 느낌.)
-"python manage.py shell"
-"from django.test.utils import setup_test_environment"
-"setup_test_environment" # 테스트 하기 전에 미리 수행하는 함수라고 생각하면됨.
-"from django.test import Client"
-"c = Client()" # 클라이언트 객체 생성
-"c" # <django.test.client.Client object at 0x105a037b8>
"from django.urls import reverse" # urls.py 파일로부터 진짜 url을 가져올 때 사용함. reverse(namespace : url name, 파라미터)
"reverse('polls:index')" # '/polls/' app_namespace : url name
"reverse('polls:results', kwargs={'pk' : 10})" # '/polls/10/results/'
"res = c.get(reverse('polls:index'))" # 클라이언트 객체를 이용해 HTTP GET 메소드를 호출할 수 있다.
"res.status_code" # 200 (요청결과 코드)
"res.content" # http response에서 중요한 body부분
"str(res.content, 'utf-8')" # utf-8로 인코딩하여 글자 그대로 볼 수 있게 함
"res.context" # 이것을 포함한 두 코드는 내가 실습 시 작동하지 않았는데 이유는 모르겠다.
"res.context['latest_question_list']" # views.py의 IndexView 클래스에서 context_object_name으로 지정한 이름을 인자로 넣을 수 있고 그에대한 쿼리셋이 넘어옴.
2. 실제 테스트 코드 작성
- tests.py에 reverse 모듈을 import 해준다.
- create_question함수는 그냥 클래스 내부에서 사용되는 것을 선언해준 것이다.
- 테스트 함수인 test_index_view_with_future_question 를 작성해준다.이후 테스트를 실행한 결과를 확인한다. "python manage.py test polls"
- 결과를 살펴보면 18번째 라인 self.assertQuerysetEqual()에서 문제가 있다고 나옴, 쿼리셋의 결과가 [] 이어야 하는데 Question 객체가 들어있음.
- 여기서 쿼리셋의 결과에 1개의 객체만 들어있는 이유는 테스트 실행시 테스트 DB에서 실행되기 때문에 그러하다는 것을 알자.
- 'latest_question_list'에 미래의 날짜를 가지는 객체는 안들어오게 만들고 싶은 상태이며 IndexView클래스 내의 get_queryset메소드를 수정해준다.
- 이후 다시 테스트를 실행한 결과를 확인한다. "python manage.py test polls"
from django.urls import reverse
def create_question(question_text, days):
time = timezone.now() + datetime.timedelta(days=days)
return Question.objects.create(question_text=question_text, pub_date = time)
class QuestionViewTests1(TestCase):
def test_index_view_with_future_question(self):
create_question(question_text='Future question', days=30)
response = self.client.get(reverse('polls:index'))
self.assertEqual(response.status_code, 200) # 상태코드가 200이야?
self.assertQuerysetEqual(response.context['latest_question_list'], []) # 쿼리셋 결과가 []이야?
from django.utils import timezone
class IndexView(generic.ListView): # 객체를 리스트 형태로 전달하기 때문에 ListView 선택
#어떤 템플릿이랑 연결할 것이고, 가져온 오브젝트를 어느 이름으로 mapping 시킬것인지.
template_name = 'polls/index.html'
context_object_name = 'latest_question_list' # index.html에서 이 이름으로 변수에 접근 가능
# 오브젝트 가져오기
def get_queryset(self):
return Question.objects.order_by('-pub_date')[:5]
class IndexView(generic.ListView): # 객체를 리스트 형태로 전달하기 때문에 ListView 선택
#어떤 템플릿이랑 연결할 것이고, 가져온 오브젝트를 어느 이름으로 mapping 시킬것인지.
template_name = 'polls/index.html'
context_object_name = 'latest_question_list' # index.html에서 이 이름으로 변수에 접근 가능
# 오브젝트 가져오기
def get_queryset(self):
return Question.objects.filter(
pub_date__lte=timezone.now() # pub_date가 현재시간보다 작은것만 필터링. 여기서 lte는 less than equal
).order_by('-pub_date')[:5]
3. tests.py에 아래의 클래스 및 메소드를 생성해 최종적으로 테스트를 마친다.
class QuestionViewTests2(TestCase):
# 아무 객체도 없는경우 아무것도 안보여줌을 테스트.
def test_index_view_with_no_questions(self):
"""
If no questions exist, an appropriate message should be displayed.
"""
response = self.client.get(reverse('polls:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No polls are available.") # 아무것도 없는경우 "No polls..."가 찍여야 함(index.html참고)
self.assertQuerysetEqual(response.context['latest_question_list'], [])
# 과거의 날짜를 가진 객체는 보여짐을 테스트.
def test_index_view_with_a_past_question(self):
"""
Questions with a pub_date in the past should be 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_index_view_with_a_future_question(self):
"""
Questions with a pub_date in the future should not be 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_index_view_with_future_question_and_past_question(self):
"""
Even if both past and future questions exist, only past questions
should be 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.>']
)
# 2개의 과거 날짜를 가진 객체가 있을 때 둘 다 보여지며, 시간순서대로 잘 정렬되어 나오는지 테스트.
def test_index_view_with_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.>']
)
'웹개발 > Django 웹서비스 개발(인프런)' 카테고리의 다른 글
37. (app2) 정적파일 적용 및 관리 (0) | 2019.02.20 |
---|---|
36. (app2) Django admin페이지 customize하기 (0) | 2019.02.20 |
34. (app2) Django 버그 수정 및 테스트 자동화하기(tests.py이용) (0) | 2019.02.20 |
33. (app2) generic view를 적용한 Class-based views 방식의 URL 라우팅 (0) | 2019.02.19 |
32. (app2) 투표결과 페이지 만들기 (result메소드 수정) (0) | 2019.02.19 |