1. Django에서의 테스트 개요
Django의 테스트는 크게 세 가지 특징이 있습니다:
- unittest 기반
Python의 unittest 모듈을 확장한 구조라 문법이 친숙합니다. - 독립적인 테스트 데이터베이스
실제 DB를 건드리지 않고, 테스트 실행 시 임시 데이터베이스가 자동으로 생성/삭제됩니다. - 다양한 테스트 도구 제공
클라이언트 시뮬레이션(self.client), ORM 테스트, API 응답 검증 등 웹 프레임워크 특화 기능을 제공합니다.
2. TestCase 기본 구조
테스트 코드는 일반적으로 앱 디렉터리 안에 있는 tests.py 혹은 tests/ 디렉터리에 작성합니다.
from django.test import TestCase
from django.contrib.auth.models import User
class UserModelTest(TestCase):
def setUp(self):
# 테스트 실행 전마다 실행됨
self.user = User.objects.create_user(username="testuser", password="password123")
def test_user_creation(self):
# User 모델이 정상적으로 생성되는지 확인
self.assertEqual(self.user.username, "testuser")
def test_user_password(self):
# 비밀번호 검증 메서드 테스트
self.assertTrue(self.user.check_password("password123"))
- setUp(): 각 테스트 실행 전마다 초기화 작업을 수행합니다.
- test_로 시작하는 메서드: 실제 검증 로직을 담습니다.
- assert 메서드: 기대값과 실제값을 비교합니다.
3. 주요 assert 메서드
테스트에서 가장 많이 쓰는 메서드 몇 가지를 정리하면 다음과 같습니다:
- self.assertEqual(a, b) → 두 값이 같은지 확인
- self.assertNotEqual(a, b) → 두 값이 다른지 확인
- self.assertTrue(x) / self.assertFalse(x) → 불리언 조건 확인
- self.assertIn(a, b) → a가 b 안에 포함되는지 확인
- self.assertRaises(Exception) → 특정 예외 발생 여부 확인
예를 들어, 회원가입 시 비밀번호가 짧으면 에러를 발생시키는 테스트를 작성할 수 있습니다:
def test_short_password(self):
with self.assertRaises(ValueError):
User.objects.create_user(username="baduser", password="123")
4. 클라이언트 시뮬레이션
Django는 내장된 테스트 클라이언트를 제공하여 실제 서버를 띄우지 않고도 HTTP 요청/응답을 테스트할 수 있습니다.
from django.urls import reverse
class LoginViewTest(TestCase):
def setUp(self):
self.user = User.objects.create_user(username="tester", password="password123")
def test_login_success(self):
response = self.client.post(
reverse("login"),
{"username": "tester", "password": "password123"}
)
self.assertEqual(response.status_code, 200)
def test_login_fail(self):
response = self.client.post(
reverse("login"),
{"username": "tester", "password": "wrongpass"}
)
self.assertEqual(response.status_code, 401)
- self.client.get(url) / self.client.post(url, data) → 요청을 시뮬레이션합니다.
- response.status_code / response.json() 등을 활용하여 결과를 검증할 수 있습니다.
5. API 테스트 (Django REST Framework와 함께)
Django REST Framework를 쓰는 경우, APIClient를 활용하면 더욱 직관적인 테스트가 가능합니다.
from rest_framework.test import APITestCase
from django.urls import reverse
from django.contrib.auth.models import User
class AuthAPITest(APITestCase):
def setUp(self):
self.user = User.objects.create_user(username="apiuser", password="password123")
def test_token_obtain(self):
url = reverse("token_obtain_pair")
response = self.client.post(url, {"username": "apiuser", "password": "password123"})
self.assertEqual(response.status_code, 200)
self.assertIn("access", response.data)
self.assertIn("refresh", response.data)
- APITestCase는 TestCase를 확장한 클래스로, JSON 응답 처리와 API 요청 테스트에 최적화되어 있습니다.
- JWT, OAuth, CRUD API 테스트에 많이 활용됩니다.
6. 커버리지 측정
테스트는 단순히 실행만 해서는 효과가 떨어집니다. coverage.py 같은 도구를 쓰면 코드의 어느 부분이 테스트되었는지 확인할 수 있습니다.
# 설치
pip install coverage
# 실행
coverage run manage.py test
# 리포트 출력
coverage report
이렇게 하면 어떤 함수가 테스트되었는지, 테스트가 누락된 부분은 어디인지 알 수 있어 품질 관리에 큰 도움이 됩니다.
7. 테스트 실행 방법
테스트 실행은 다음과 같이 간단합니다:
python manage.py test
특정 앱이나 모듈만 실행하려면:
python manage.py test myapp.tests.UserModelTest
마치며
이번 글에서는 Django TestCase 작성 방법을 기초부터 실습 예제까지 살펴봤습니다.
정리하면:
- Django 테스트는 unittest 기반이며 독립적인 DB 환경에서 실행됩니다.
- TestCase, APITestCase를 활용하면 모델, 뷰, API까지 손쉽게 검증할 수 있습니다.
- self.client를 이용해 클라이언트 요청을 시뮬레이션할 수 있습니다.
- coverage와 같은 도구를 함께 사용하면 테스트 범위를 수치로 관리할 수 있습니다.
테스트 작성은 처음에는 번거롭지만, 프로젝트가 커질수록 유지보수 비용을 크게 줄여줍니다. 작은 단위부터 꾸준히 작성해 나가면, 안정적이고 신뢰할 수 있는 서비스를 만드는 데 큰 도움이 될 것입니다.
'백엔드' 카테고리의 다른 글
CSRF와 XSS 방어 (1) | 2025.09.18 |
---|---|
Docker 멀티 컨테이너와 Compose, CI/CD 배포 (0) | 2025.09.02 |
Django ORM, 이것만 알면 된다! 개념·종류·실습 올인원 가이드 (2) | 2025.08.21 |
Django REST Framework 기초와 JWT 인증 이해하기 (1) | 2025.08.20 |
Django ORM 기초: 개념과 예제 (2) | 2025.06.20 |