졍
지영이 블로그
졍
전체 방문자
오늘
어제
  • 분류 전체보기 (95)
    • 네트워크 (12)
    • 시스템설계 (6)
    • AWS (7)
    • Elasticsearch (3)
    • Python (5)
    • 자료구조, 알고리즘 (9)
    • 코딩테스트 (29)
    • NCP (8)
    • 운영체제 (7)
    • 개인 프로젝트 (8)
    • Github (1)
    • 여행 (0)
      • 2024동유럽 (0)
    • 대학원 (0)
      • 논문정리 (0)

최근 글

최근 댓글

hELLO · Designed By 정상우.
졍

지영이 블로그

[Django] 테스트 코드 작성해보기
Python

[Django] 테스트 코드 작성해보기

2023. 6. 3. 15:52

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
    졍
    졍

    티스토리툴바