노트

DRF API 테스트

Testing APIs with Django REST Framework

백엔드#django#testing · 연결된 개념 5개

쉽게 말하면

DRF API 테스트는 소방 훈련처럼 연습용 건물에서 '익명은 리뷰를 못 쓴다' 같은 상황을 실제 요청으로 재현해 보는 거예요. 훈련이 끝나면 흔적이 치워져서 진짜 데이터는 건드리지 않죠.

비유가 깨지는 곳 실제로는 테스트용 DB를 따로 만들고 각 테스트를 트랜잭션으로 감싸 되돌려요. force_authenticate는 인증을 건너뛰니 권한 로직용이고, 토큰 인증 자체는 헤더를 넣어 시험해요.

DRF는 장고 테스트 위에 API 요청을 편하게 보내는 APITestCase와 APIClient를 제공한다. 장고 테스트 러너(test runner)는 테스트용 DB를 따로 만들고, 각 테스트를 트랜잭션으로 감싸 끝나면 되돌리므로 실제 데이터를 건드리지 않는다.

from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
 
class ReviewTests(APITestCase):
    def setUp(self):
        self.user = User.objects.create_user("alice", password="pw-1234")
        self.movie = Movie.objects.create(title="Dune")
 
    def test_anonymous_cannot_create_review(self):
        res = self.client.post(reverse("review-create", args=[self.movie.pk]), {"rating": 5})
        self.assertEqual(res.status_code, status.HTTP_401_UNAUTHORIZED)
 
    def test_author_can_create_review(self):
        self.client.force_authenticate(user=self.user)
        res = self.client.post(reverse("review-create", args=[self.movie.pk]), {"rating": 5}, format="json")
        self.assertEqual(res.status_code, status.HTTP_201_CREATED)
        self.assertEqual(Review.objects.get().author, self.user)

작성 순서

  1. 파일·메서드 이름을 test로 시작한다(tests.py, test_*.py). 러너가 이 이름으로 찾는다
  2. setUp이나 팩토리(test data factory)로 테스트 데이터를 만든다
  3. URL은 하드코딩하지 말고 reverse()로 만든다
  4. 응답 상태 코드와 본문, 그리고 DB에 남은 결과까지 확인한다

인증이 필요한 요청

  • force_authenticate(user=...): 인증 과정을 건너뛰고 사용자를 지정한다. 권한 로직을 시험할 때 쓴다
  • 토큰 인증 자체를 시험하려면 self.client.credentials(HTTP_AUTHORIZATION="Token " + token.key)로 헤더를 넣는다(DRF 인증과 권한)
  • 401(인증 없음)과 403(권한 없음)을 나눠 확인하면 인증·권한 설정 실수를 잡기 좋다

무엇을 테스트할까

뷰 하나하나보다 "익명은 못 쓴다", "작성자만 고친다", "같은 사람이 리뷰를 두 번 못 쓴다" 같은 행동 단위로 이름을 붙인다. 이런 API 테스트는 테스트 피라미드의 중간층에 해당하고, 변경할 때 안전망이 된다(자가 테스트 코드). 불안정하거나 읽기 어려운 테스트의 징후는 테스트 냄새를 본다.

출처: DRF Testing: APIClient · Forcing authentication · credentials

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • DRF 뷰 계층

    DRF는 같은 API를 점점 더 적은 코드로 쓰게 해 주는 뷰 계층을 제공한다. 함수 뷰 → APIView → 제네릭 뷰(generic view)와 믹스인(mixin) → 구체 제네릭 뷰 → ViewSet과 Router 순으로 올라갈수록 관례가 많아지고 코드가 줄어든다.

  • React Testing Library

    React Testing Library(RTL)는 컴포넌트를 jsdom 같은 테스트용 DOM(Document Object Model) 환경에 렌더하고, 사용자가 실제로 쓰는 방식으로 요소를 찾고 조작하게 해 주는 테스트 도구다. 내부 구현(state, 메서드)이 아니라 화면에 보이는 동작을 검증하라는 철학을 강하게 가진 라이브러리다.

  • 인증과 인가

    인증(authentication)은 "너는 누구냐"를 확인하는 것이고, 인가(authorization)는 "너는 이걸 해도 되냐"를 판단하는 것이다. 인증이 먼저고 인가가 그다음이다.

  • DRF 필터·검색·정렬

    DRF의 목록 API는 쿼리 파라미터로 결과를 좁히는 세 가지 장치를 붙일 수 있다. 값이 정확히 맞는 것만 고르는 필터, 일부 문자열로 찾는 검색, 순서를 바꾸는 정렬이다. 모두 제네릭 뷰(GenericAPIView 계열)의 filter_backends로 적용된다.

  • DRF 파서·렌더러와 콘텐츠 협상

    DRF에서 파서(Parser)는 요청 본문을 파이썬 자료형으로 바꾸고, 렌더러(Renderer)는 응답 데이터를 클라이언트가 받을 형식으로 바꾼다. 어떤 렌더러를 쓸지는 요청의 Accept 헤더를 보고 고르는데, 이를 콘텐츠 협상(content negotiation)이라 한다.

보기 옵션