💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    08 단위 테스트(TestCase) 작성 및 실행 | ✅ 편저: 코담 운영자

    Django 웹 프로그래밍 강좌 8강 - 단위 테스트(TestCase) 작성 및 실행 (Django 5.2 기준)

    강의 영상:

    이 강의는 Django 공식 문서의 2.2 튜토리얼 내용을 바탕으로 진행되며, Django 5.2 버전에 맞춰 테스트 관련 기능들을 실습 중심으로 설명합니다.

    📚 공식문서 주소: https://docs.djangoproject.com/ko/5.2/intro/tutorial05/


    1. 테스트란?

    테스트(Test)는 코드가 예상대로 동작하는지 확인하는 자동화된 검증 절차입니다. Django는 unittest 모듈을 기반으로 한 TestCase 클래스를 통해 테스트를 지원합니다.

    테스트의 주요 목적:

    1. 코드 변경으로 인한 버그를 조기에 발견
    2. 협업 환경에서 안정성 확보
    3. 개발 생산성 향상 및 리팩토링 안정성 확보

    테스트 코드는 문서보다 신뢰할 수 있는 코드의 실행 보증 수단입니다.


    2. 테스트 작성 위치 및 규칙

    • 테스트 파일명은 test_*.py 형식
    • 앱 디렉토리 내부 (예: polls/tests.py)
    • 클래스명은 Test*, 메서드명은 test_로 시작해야 Django가 테스트로 인식합니다

    테스트 실행 명령어:

    python manage.py test
    
    • 해당 명령어는 프로젝트 내 모든 앱의 테스트를 자동 탐색 및 실행합니다
    • 각 테스트의 성공/실패 여부가 콘솔에 출력됩니다

    3. 모델 메서드 테스트 예시

    Question.was_published_recently() 메서드에 대한 테스트를 작성해봅니다.

    polls/tests.py

    import datetime
    from django.utils import timezone
    from django.test import TestCase
    from .models import Question
    
    class QuestionModelTests(TestCase):
    
        def test_was_published_recently_with_future_question(self):
            time = timezone.now() + datetime.timedelta(days=30)
            future_question = Question(pub_date=time)
            self.assertIs(future_question.was_published_recently(), False)
    
    • 미래 날짜의 질문은 was_published_recently() 결과가 False여야 합니다
    • assertIs()는 기대한 값과 실제 값이 같은지를 검사합니다

    테스트 실패 시 어떤 조건에서 실패했는지 상세 로그가 출력되어 디버깅에 유리합니다


    4. View 테스트: 클라이언트 시뮬레이션

    Django의 테스트 클라이언트는 실제 사용자가 브라우저를 통해 요청을 보내는 것처럼 작동합니다.

    테스트 예시:

    from django.urls import reverse
    from .models import Question
    from django.utils import timezone
    
    class QuestionIndexViewTests(TestCase):
        def test_no_questions(self):
            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"], [])
    
    • self.client.get(...): 가상의 GET 요청 실행
    • assertContains(): 응답 본문에 특정 텍스트가 포함되어 있는지 검사
    • assertQuerySetEqual(): 응답에 포함된 쿼리셋이 예상과 일치하는지 확인

    5. 테스트 유틸 함수와 시간 조건 필터링

    뷰에서 미래 시점의 게시물은 노출되지 않아야 함. 따라서 시간 조건에 따른 테스트도 필요합니다.

    헬퍼 함수로 테스트 데이터 생성

    def create_question(question_text, days):
        time = timezone.now() + datetime.timedelta(days=days)
        return Question.objects.create(question_text=question_text, pub_date=time)
    
    • days > 0: 미래 게시물, days < 0: 과거 게시물

    다양한 조건에 대한 테스트 작성

    class QuestionIndexViewTests(TestCase):
    
        def test_past_question(self):
            question = create_question("Past question", -30)
            response = self.client.get(reverse("polls:index"))
            self.assertContains(response, question.question_text)
    
        def test_future_question(self):
            create_question("Future question", 30)
            response = self.client.get(reverse("polls:index"))
            self.assertContains(response, "No polls are available.")
            self.assertQuerySetEqual(response.context["latest_question_list"], [])
    
    • 미래 질문은 리스트에 노출되지 않아야 하며, 테스트로 이 조건을 보장할 수 있습니다

    6. 테스트가 중요한 이유 정리

    • 테스트는 코드 안정성과 협업 효율성을 동시에 확보할 수 있는 도구입니다
    • 코드 변경 시 문제를 빠르게 발견할 수 있어 유지보수가 쉬워집니다
    • 테스트가 통과하면 해당 기능이 정상 작동한다는 확신을 줄 수 있습니다
    • CI/CD 파이프라인과도 쉽게 통합되어 자동 검증이 가능합니다

    마무리 요약

    • Django는 unittest 기반의 테스트 프레임워크를 기본 제공
    • TestCase를 상속받아 모델/뷰 테스트 가능
    • 클라이언트 시뮬레이션을 통한 실제 요청 테스트가 가능함
    • 시간 조건, 예외 조건 등 다양한 상황을 테스트할 수 있음
    • 테스트는 코드의 신뢰성과 안정성을 확보하는 핵심 도구

    다음 강의 예고

    9강에서는 CSS 및 static 파일 연결을 통해 정적인 디자인 리소스를 Django에 적용하는 방법을 학습합니다.

    감사합니다.

    TOP
    preload preload