TestCase vs APITestCase

김기훈·2026년 2월 11일

이론

목록 보기
5/10

차이

  • TestCase → 모델/로직 테스트

  • APITestCase → REST API 테스트 전용, JSON/인증 지원

---

기능TestCaseAPITestCase
기본 clientDjango clientDRF 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 클라이언트
responseAPI 응답 객체
payload요청에 담을 데이터(Dict)
assertEqual두 값이 같은지 검증
assertIn요소 포함 여부 검증
statusHTTP 상태 코드 상수
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의 APITestCaseAPIClient 를 사용하며 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 상태 코드 상수)

  • HTTP 상태 코드를 숫자 대신 상수로 표현
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"]
profile
안녕하세요.

0개의 댓글