일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 알고리즘 공부방법
- string 함수
- 입출력 패턴
- 이분그래프
- string 메소드
- iOS14
- Django Nodejs 차이점
- 프레임워크와 라이브러리의 차이
- EOF
- double ended queue
- Django의 편의성
- 구조체와 클래스의 공통점 및 차이점
- UI한글변경
- 장고란
- getline
- 자료구조
- k-eta
- 매크로
- 입/출력
- vscode
- scanf
- c++
- 백준
- 시간복잡도
- 2557
- correlation coefficient
- 표준 입출력
- 연결요소
- 엑셀
- Django란
- Today
- Total
Storage Gonie
34. (app2) Django 버그 수정 및 테스트 자동화하기(tests.py이용) 본문
34. (app2) Django 버그 수정 및 테스트 자동화하기(tests.py이용)
Storage Gonie 2019. 2. 20. 02:23주제 : Model Question의 was_published_recently메소드를 자동으로 테스트하는 코드 작성하기.(테스트를 자동화하는 코드 작성)
# TDD(Test-driven development)
- 테스트를 먼저 작성하는 개발 방법론.
- 개발자는 먼저 요구사항(제약조건)을 검증하는 자동화된 테스트 케이스를 작성한다.
- 그 다음 그 테스트 케이스를 통과하기 위한 최소한의 코드를 생성한다. 마지막으로 작성한 코드를 표준에 맞게 리팩토링한다.
Question의 was_published_recently메소드에는 작은 버그가 하나 있다.
published_recently로 인식시키고 싶은 것은 ((하루전~현재)) 까지만 인데 ((현재~미래))도 published_recently로 인식된다는 것이다.
이런 버그를 인식하게 돕는 테스트를 자동화 해주는 코드를 작성할 수 있다.
"python manage.py shell"
"import datetime"
"from django.utils import timezone"
"from polls.models import Question"
"fq = Question(pub_date = timezone.now() + datetime.timedelta(days = 2)) "
"fq.was_published_recently()"
-> True # ((현재~미래))의 날짜에 대해 원래 나왔으면 하는 결과는 False인데 True가 나온것이다.
1. tests.py에 TestCase를 상속받는 클래스 생성 후 메소드 추가
import datetime
from django.utils import timezone
class SomeTest(TestCase):
def abc(self): # 테스트 실행시 자동으로 호출되지 않음.
print("abc")
2. 자동화된 테스트 실행
- "python manage.py test polls"
- Ran이 0개라고 뜨면서 아무것도 실행되지 않음.
3. 메소드의 이름을 test로 시작하도록 수정.
- 테스트 메소드는 반드시 'test'로 이름이 시작되어야 함
import datetime
from django.utils import timezone
class SomeTest(TestCase):
def test_abc(self): # 테스트를 실행했을 때 자동으로 실행되게 하기 위해서는 이름이 'test'로 시작해야한다.
print("test abc")
4. 자동화된 테스트 재실행
- "python manage.py test polls"
- Ran이 1개라고 뜨면서 테스트 1개가 실행된 상태.
- test_abc()메소드는 정상적으로 호출되었는데 실제적으로 True, False와 같이 테스트 된건 없음
5. 테스트 되는 조건 추가
- self.assert~가 테스트의 핵심 메소드 들이다.
- 여러가지가 있는데 여기서는 self.assertIs(테스트 하고픈 조건, 기대하는 Boolean값)를 사용하여 테스트를 진행한다.
- 5 > 3은 원래 True인데 기대값에 False를 고의로 적어놨더니 FAILED가 뜬 것을 볼 수 있다.
- 이를 이용해서 was_published_recently를 테스트하는 메소드를 작성해보자.
class SomeTest(TestCase):
def test_abc(self): # 테스트를 실행했을 때 자동으로 실행되게 하기 위해서는 이름이 'test'로 시작해야한다.
print("test abc")
self.assertIs(5 > 3, False) # (테스트 하고픈 조건, 기대하는 Boolean 값)
6. 위의 클래스를 지워버리고 다음의 클래스 및 메소드로 교체해서 이제 본 작업에 진입.
- "python manage.py test polls"
- 테스트 코드에서 우리가 기대하는 것을 작성해 두었는데 이를 실행한 결과가 FAILED 했다.
- 이는 테스트한 부분에 버그가 있고, 수정해야함을 의미한다.
class QuestionMethodsTests(TestCase):
def test_was_published_recently_with_future_question(self):
time = timezone.now() + datetime.timedelta(days=7) # 현재 + 7일 즉, 미래의 날짜.
future_question = Question(pub_date = time)
self.assertIs(future_question.was_published_recently(), False)
7. 문제가 생긴 부분의 버그 수정
- models.py에서 Question의 was_published_recently()를 수정
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
8. 다시 테스트 코드 실행
- "python manage.py test polls"
- 성공적으로 테스트를 통과함.
9. 좀 더 다양한 테스트 추가
- "python manage.py test polls"
- 성공적으로 테스트들을 통과함.
class QuestionMethodsTests(TestCase):
# 7일 미래의 시간을 테스트하는 코드
def test_was_published_recently_with_future_question(self):
time = timezone.now() + datetime.timedelta(days=7) # 현재 + 7일 즉, 미래의 날짜.
future_question = Question(pub_date = time)
self.assertIs(future_question.was_published_recently(), False)
# 30일 전의 시간을 테스트 하는 코드
def test_was_published_recently_with_old_question(self):
""" was_published_recently() should return False for questions whose pub_date is older than 1 day. """
time = timezone.now() - datetime.timedelta(days=30)
old_question = Question(pub_date=time)
self.assertIs(old_question.was_published_recently(), False)
# 1시간 전의 시간을 테스트 하는 코드
def test_was_published_recently_with_recent_question(self):
""" was_published_recently() should return True for questions whose pub_date is within the last day. """
time = timezone.now() - datetime.timedelta(hours=1)
recent_question = Question(pub_date=time)
self.assertIs(recent_question.was_published_recently(), True)
** 귀찮지만 유닛테스트 같은것을 해주는게 좋은 습관이다.
'웹개발 > Django 웹서비스 개발(인프런)' 카테고리의 다른 글
36. (app2) Django admin페이지 customize하기 (0) | 2019.02.20 |
---|---|
35. (app2) view 및 템플릿 테스트하기 (0) | 2019.02.20 |
33. (app2) generic view를 적용한 Class-based views 방식의 URL 라우팅 (0) | 2019.02.19 |
32. (app2) 투표결과 페이지 만들기 (result메소드 수정) (0) | 2019.02.19 |
31. (app2) POST 처리 (투표결과 DB반영하기) (0) | 2019.02.19 |