차이
TestCase → 모델/로직 테스트
APITestCase → REST API 테스트 전용, JSON/인증 지원
---
| 기능 | TestCase | APITestCase |
|---|
| 기본 client | Django client | DRF APIClient |
| JSON POST 편의성 | ❌ 번거로움 | ✅ format="json" 자동 처리 |
| 인증 테스트 | ❌ 직접 cookie/session 조작해야 함 | ✅ .force_authenticate() 제공 |
| API 응답(JSON) 확인 | ❌ 해야함 | ✅ .data 자동 파싱 |
| REST API 테스트 목적 | ❌ 적합하지 않음 | ✅ 최적화 |
TestCase
Django 기본 제공 테스트 클래스
언제 사용?
- 모델(Model) 테스트
- ORM 동작 테스트
- 비즈니스 로직(서비스/유틸) 테스트
- Django 기본 View 테스트
특징
- Django 테스트 DB 자동 생성 & 롤백
- 기본 Django Client 사용 (form 중심)
- JSON 요청 테스트는 불편함
예시
from django.test import TestCase
from apps.questions.models import QuestionCategory
class CategoryModelTests(TestCase):
def test_category_name(self):
category = QuestionCategory.objects.create(name="백엔드")
self.assertEqual(category.name, "백엔드")
APITestCase
DRF가 제공하는 API 테스트 클래스
언제 사용?
- REST API endpoint 테스트
- JSON 요청/응답 테스트
- 인증이 필요한 API 테스트 (JWT, Session 등)
- POST, PUT, DELETE 테스트 등이 중요할 때
특징
- DRF의 APIClient 자동 제공
- JSON 요청 보낼 때 자동으로 content-type 설정됨
.force_authenticate() 등 강력한 기능 있음
- REST API 테스트에 최적화됨
예시
from rest_framework.test import APITestCase
from rest_framework import status
class QuestionCreateTests(APITestCase):
def test_question_create(self):
response = self.client.post(
"/api/v1/questions",
{"title": "hello", "content": "world"},
format="json"
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
자주 사용하는 용어·메서드
| 용어 | 의미 |
|---|
| client | 테스트용 HTTP 클라이언트 |
| response | API 응답 객체 |
| payload | 요청에 담을 데이터(Dict) |
| assertEqual | 두 값이 같은지 검증 |
| assertIn | 요소 포함 여부 검증 |
| status | HTTP 상태 코드 상수 |
| force_authenticate | 인증된 요청 테스트 |
| setUp / setUpTestData | 테스트용 초기 데이터 생성 |
client (테스트 클라이언트)
- Django/DRF에서 요청을 보내기 위해 사용하는 가짜 HTTP 클라이언트 (실제 서버 없이도 view를 테스트할 수 있음)
주요 메서드
client.get(url, data, format)
client.post(url, data, format)
client.put(url, data, format)
client.patch(url, data, format)
client.delete(url, data, format)
- DRF의
APITestCase 는 APIClient 를 사용하며 JSON 요청을 쉽게 보낼 수 있음
response (응답 객체)
- 요청을 보낸 후 서버가 반환한 응답을 담고 있는 객체
주요 속성
response.status_code → HTTP 상태 코드 (200, 201, 400 등)
response.data → JSON 응답 자동 파싱(DRF 전용)
response.content → 응답 원본(byte)
response.json() → JSON 파싱(Django 기본 client 사용 시)
payload (요청 데이터)
- POST, PUT 등에 포함되는 전송할 데이터 / 테스트 코드에서는 보통 dict 형태로 작성함
payload = {
"title": "테스트 제목",
"content": "테스트 내용",
assert 메서드들 (검증)
- 예상한 값과 실제 결과가 일치하는지 검증
assert 메서드
assertEqual(a, b) → a == b 인지 비교
assertNotEqual(a, b) → a != b 인지 비교
assertTrue(x) → x가 True인지 검증
assertFalse(x) → x가 False인지 검증
assertIn(item, container)
- item이 container(list, dict, string 등)에 포함되는지 검증
assertNotIn(item, container) → item이 container에 없는지 검증
assertIsNone(x) → 값이 None인지 검증
assertIsNotNone(x) → 값이 None이 아닌지 검증
assertGreater(a, b) → a > b
assertGreaterEqual(a, b) → a >= b
assertLess(a, b) → a < b
setUp / setUpTestData
- 테스트 전에 공통으로 필요한 데이터를 준비할 때 사용
setUp()
- 테스트 매번 실행 전에 실행됨
- 매 테스트마다 fresh한 데이터가 필요할 때 사용
def setUp(self):
self.user = User.objects.create(...)
setUpTestData()
- 클래스 전체에서 딱 1번만 실행됨
- 많은 데이터가 필요할 때 속도 빠름 (DB insert 한 번만 발생)
@classmethod
def setUpTestData(cls):
cls.user = User.objects.create(...)
force_authenticate (DRF 전용)
- 테스트 클라이언트를 강제로 인증 상태로 만들 때 사용
self.client.force_authenticate(user=self.user)
- JWT 토큰 필요 없이 인증된 요청을 만들 수 있어 API 테스트가 매우 쉬워짐
reverse (URL name으로 URL 생성)
- URL을 하드코딩하지 않고 라우터 이름을 기반으로 URL을 가져옴
from django.urls import reverse
url = reverse("question-create")
status (DRF 상태 코드 상수)
from rest_framework import status
status.HTTP_200_OK
status.HTTP_201_CREATED
status.HTTP_400_BAD_REQUEST
status.HTTP_403_FORBIDDEN
status.HTTP_404_NOT_FOUND
fixtures (고정 데이터)
- 테스트 실행 시 미리 로드할 JSON/파일 기반 데이터
fixtures = ["users.json", "categories.json"]