Django 튜토리얼의 챕터 5가 테스트 작성에 대한 내용이다.
'테스트 코드'에 대해 들어는 봤지만 실제로 작성해보기는 처음이기 때문에 왜 필요한지, 어떻게 작성하는지 기록해두고자 한다.
https://docs.djangoproject.com/ko/4.2/intro/tutorial05/
Django
The web framework for perfectionists with deadlines.
docs.djangoproject.com
테스트 코드란?
말 그대로 내가 개발한 것에 대한 테스트를 수행하는 코드이다.
내가 개발한 코드가 원하는 대로 동작을 하더라도, 비정상 상황에 대해 정상인것 처럼 작동한다면 문제가 있는 코드이다.
특히 코드를 수정할 때 기존 코드와 꼬여 예상치 못한 동작을 하게 될 수 있는데, 이 경우 테스트 코드가 버그를 잡아낼 수 있도록 도와준다.
코드를 수정할 때마다 매번 비정상 동작에 대한 검수를 하나하나 할 수 없기 때문에, Django에서는 이를 코드로 짜두고 자동화 테스트를 지원한다.
테스트 코드 짜보기
class Question(models.Model):
question_text = models.CharField(max_length=200) # 문자
pub_date = models.DateTimeField("date published") # 날짜와 시간
def __str__(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1) # 1일 이내 작성된 경우
Question이라는 모델에 pub_date라는 변수가 존재한다. 이는 Question 객체가 언제 생성되었는지를 저장하는 변수이다.
해당 클래스의 was_published_recently() 함수를 통해, Question 객체가 1일 이내에 생성되었는지 아닌지를 판별한다.
이때, pub_date에 미래의 시간이 저장되는 경우에도 was_published_recently() 함수가 True를 리턴하는 반례가 생긴다.
이를 shell로 확인해볼 수 있다.
이에 대한 test 코드는 다음과 같이 짤 수 있다. (test 코드는 테스트하고자하는 객체가 존재하는 애플리케이션의 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 question 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) # 결과가 False인지 검증
Question model에 대한 검증이라는 것을 명시하는 QuestionModelTests 클래스를 만들고, 그 안에 세부 메소드를 작성하도록 한다.
test_was_published_recently_with_future_question() 함수에서는, 현재로부터 30일 이후의 날짜를 pub_date로 가지는 future_question 객체를 생성한다.
그리고 assertIs()함수를 통해 future_question 객체에 대해 was_published_recently()를 수행하고 이 결과가 False가 나오는지 검증한다.
코드를 작성하고 python manage.py test <app_name>으로 코드를 실행하면 다음과 같이 뜬다.
결과를 통해 tests.py의 어떤 테스트가 실패했는지, 몇번째 줄에서 발생했는지, 원래 나와야 하는 값과 어떻게 다른지에 대해 상세하게 알 수 있다!
python manage.py test <app_name> 명령어를 수행했을 때 Django에서는 다음과 같은 순서로 테스트를 수행한다.
1. 입력한 app_name의 애플리케이션에서 테스트를 찾는다.
2. django.test.TestCase의 subclass가 존재하는지 찾는다.
3. 테스트를 목적으로하는 별도의 데이터베이스를 생성한다.
4. 함수 이름이 "test"로 시작하는 것들을 찾아 테스트를 수행한다.
앞으로 코드를 작성할때 때 발생할 수 있는 예외사항을 다양하게 고려해보고, 이를 테스트로 짜는 연습을 많이 해봐야할 것 같다.
+)코드 수정 후, 테스트에 통과하면 결과가 다음과 같이 나온다.
'Python' 카테고리의 다른 글
[Python Framework] 파이썬 프레임워크와 웹서버 연동 - CGI, WSGI, ASGI 차이 (0) | 2023.06.16 |
---|---|
[Python] Mutable, Immutable 차이 (1) | 2023.06.07 |
[Flask] MVC pattern (0) | 2023.05.06 |
[Python] Set과 List의 시간 복잡도 차이 (0) | 2023.05.04 |