Django

Chapter 12-1 Django TDD(Test-Driven Development)란?

Chansman 2025. 5. 19. 18:17

✅ TDD(Test-Driven Development)란?

TDD는 테스트를 먼저 작성하고, 그 테스트를 통과하는 코드를 나중에 작성하는 개발 방법론입니다.

🔁 핵심 사이클 (Red → Green → Refactor)

  1. Red: 실패하는 테스트 작성
  2. Green: 테스트 통과를 위한 최소 코드 작성
  3. Refactor: 중복 제거 및 코드 개선

📌 TDD의 장
점과 단점

✔️ 장점

  • 코드 품질 향상: 동작 보장이 명확
  • 버그 예방: 요구사항 기반 테스트
  • 안정된 리팩토링: 변경 후에도 테스트로 기능 확인 가능
  • 요구사항 명확화: 테스트를 작성하며 요구를 구체화

❌ 단점

  • 초기 시간 소모: 테스트 작성 시간 필요
  • 복잡성 증가: 로직이 복잡할수록 테스트도 어려움
  • 테스트 과잉 위험: 비효율적인 테스트 증가 가능

✅ setUp() 메서드를 포함한 예시

from django.test import TestCase
from .models import MyModel

class MyModelTest(TestCase):
    def setUp(self):
        # 테스트 전에 실행되는 설정 코드
        self.my_model = MyModel.objects.create(name="Test")

    def test_model_creation(self):
        # setUp에서 만든 객체 사용
        self.assertEqual(self.my_model.name, "Test")

 


📌 정리

메서드역할
setUp() 각 테스트 메서드가 실행되기 직전에 항상 호출됨. 테스트에 필요한 공통 객체를 초기화
test_... 실제로 테스트를 수행하는 메서드. 이름이 test_로 시작해야 테스트로 인식됨
 

🧠 팁

  • setUp()은 각 테스트마다 새로 실행되므로 테스트 간 독립성을 유지할 수 있음.
  • 여러 테스트에서 동일한 데이터를 사용할 경우 코드 중복을 줄일 수 있음.

🧪 Django에서의 테스트 코드 작성

Django는 unittest 기반의 테스트 프레임워크를 자체 제공하며, 각 앱의 tests.py 또는 별도 tests/ 폴더에서 테스트 코드를 작성합니다.

from django.test import TestCase
from .models import MyModel

class MyModelTest(TestCase):
    def test_model_creation(self):
        my_model = MyModel.objects.create(name="Test")
        self.assertEqual(my_model.name, "Test")

🔨 Django에서의 TDD 실천 순서

1. 테스트 작성 (Red 단계)

def test_example(self):
    response = self.client.get('/my-url/')
    self.assertEqual(response.status_code, 200)

2. 최소한의 코드 작성 (Green 단계)

from django.http import HttpResponse

def my_view(request):
    return HttpResponse("Hello, World!")

3. 리팩토링 (Refactor 단계)

  • 중복 제거
  • 메서드 분리
  • 코드 간결화 등

🧰 주요 테스트 유형 예시

📦 모델 테스트

class MyModelTest(TestCase):
    def test_str_method(self):
        my_model = MyModel(name="Test")
        self.assertEqual(str(my_model), "Test")

🌐 뷰 테스트

from django.urls import reverse

class MyViewTest(TestCase):
    def test_view_url_exists(self):
        response = self.client.get(reverse('my_view'))
        self.assertEqual(response.status_code, 200)

📝 폼 테스트

from .forms import MyForm

class MyFormTest(TestCase):
    def test_valid_form(self):
        form = MyForm(data={'name': 'Test'})
        self.assertTrue(form.is_valid())

    def test_invalid_form(self):
        form = MyForm(data={'name': ''})
        self.assertFalse(form.is_valid())

📣 시그널 테스트

class MySignalTest(TestCase):
    def test_post_save_signal(self):
        with self.assertLogs('myapp', level='INFO') as cm:
            MyModel.objects.create(name="Test")
        self.assertIn('Signal triggered', cm.output[0])

🧪 테스트 실행 방법

전체 테스트 실행

python manage.py test

특정 앱 테스트 실행

python manage.py test <app_name>

📚 참고자료