Django + DRF 프로젝트에서 Automated Testing을 늦게 도입하기: Setup, Requirements, 그리고 Best Practices - Part-1

발행: (2025년 12월 12일 오후 12:01 GMT+9)
6 min read
원문: Dev.to

Source: Dev.to

많은 Django REST Framework 프로젝트는 빠른 기능 개발과 자동화된 테스트 스위트 없이 시작됩니다. 처음에는 생산성이 높아 보이지만, 외래키가 늘어나고, 직렬화기가 중첩되며, 시스템 복잡도가 증가함에 따라 수동 테스트는 깨지기 쉽고 매우 시간이 많이 소요됩니다.

이 두 파트 시리즈에서는 기존 Django REST Framework 프로젝트에 pytest를 도입하는 방법을 정확히 보여줍니다. 개발이 깊이 진행된 상황이라도 적용할 수 있습니다.

파트 1에서 다루는 내용

  • 왜 pytest가 Django + DRF에 이상적인가
  • pytest 설치 및 프로젝트 수준 설정 구성
  • 별도의 테스트 설정 파일 만들기
  • 전용 PostgreSQL 테스트 데이터베이스 설정
  • API 클라이언트와 테스트 사용자를 위한 fixture 구축
  • 커스텀 사용자 모델을 안전하게 다루기
  • 테스트를 안정적으로 실행하도록 프로젝트 준비하기

파트 2에서는 Blog → Writer → Category → SocialMediaMeta 사용 사례를 활용한 실제 테스트 사례를 보여줄 예정입니다.


나중에 테스트를 추가하는 이유는?

많은 팀이 테스트를 미루는 경우:

  • 모델이 안정화될 때까지
  • 뷰와 직렬화기에 로직이 쌓이기 시작할 때까지
  • 수동 테스트가 느리거나 오류가 발생하기 시작할 때까지
  • 리팩터링이 위험해질 때까지
  • 버그가 반복적으로 나타날 때까지
  • 새로운 개발자를 온보딩하는 것이 번거로워질 때까지

좋은 소식: pytest는 테스트 구성을 올바르게 분리하기만 하면 규모가 크고 활발히 운영되는 Django 프로젝트에도 깔끔하게 통합됩니다.

pytest와 필수 플러그인 설치

pip install pytest pytest-django pytest-cov Faker

이 도구들이 제공하는 기능:

  • pytest – 빠르고 표현력이 풍부한 테스트
  • pytest-django – Django ORM, fixture, DB 설정 지원
  • pytest-cov – 코드 커버리지 측정
  • Faker – 무작위 테스트 데이터 생성

프로젝트 루트에 pytest.ini 만들기

[pytest]
DJANGO_SETTINGS_MODULE = project.settings.test
python_files = tests.py test_*.py *_tests.py
addopts = --reuse-db -x

핵심 포인트

  • pytest가 테스트 설정 파일을 명시적으로 가리키도록 함.
  • --reuse-db 로 테스트 속도를 크게 향상시킴.
  • -x 는 첫 번째 실패 시 테스트를 중단 (선택 사항이지만 초기에는 유용).

settings/test.py 만들기

from .local import *

DATABASES["default"]["NAME"] = "test_db"
AUTH_PASSWORD_VALIDATORS = []

TEST_USER = {
    "id": 999,
    "email": "testuser@example.com",
}

(a) 별도 데이터베이스

테스트가 개발 DB를 건드리지 않도록 함.

(b) 비밀번호 검증 비활성화

테스트가 비밀번호 복잡성 요구사항 때문에 실패하지 않게 함.

(c) TEST_USER

복잡한 회원가입 흐름(OTP, 이메일 인증, 커스텀 사용자 매니저 로직)을 우회할 수 있게 함.

PostgreSQL: 전용 테스트 데이터베이스 만들기

CREATE DATABASE test_db;
GRANT ALL PRIVILEGES ON DATABASE test_db TO your_db_user;
ALTER DATABASE test_db OWNER TO your_db_user;

데이터베이스를 직접 생성하면 다음과 같은 끔찍한 오류를 피할 수 있습니다:

permission denied to create database

tests/ 디렉터리 구조 추가

tests/
│── __init__.py
│── conftest.py
│── test_blog_creation.py
│── test_blog_listing.py
│── test_nested_blog_response.py
│── test_signals_blog_metadata.py

여기서 핵심 파일은 conftest.py 입니다.

중요한 Fixture가 포함된 conftest.py 만들기

import pytest
from django.contrib.auth import get_user_model
from blogs.models import Writer, Category

@pytest.fixture
def test_user(db, settings):
    User = get_user_model()
    data = settings.TEST_USER
    return User.objects.create(
        id=data["id"],
        email=data["email"],
        is_active=True,
    )

@pytest.fixture
def api_client(test_user):
    from rest_framework.test import APIClient
    client = APIClient()
    client.force_authenticate(test_user)
    return client

@pytest.fixture
def writer(db):
    return Writer.objects.create(
        name="Jane Writer",
        email="jane@example.com",
    )

@pytest.fixture
def category(db):
    return Category.objects.create(
        title="Technology",
        slug="tech",
    )

이 fixture들이 제공하는 것:

  • 인증된 API 클라이언트 (로그인/OTP 단계 없이)
  • 재사용 가능한 테스트 사용자
  • 안정적인 외래키 의존성

처음으로 테스트 실행하기

pytest -s

모든 설정이 올바르게 구성되었다면, pytest가 테스트 데이터베이스를 생성하고 테스트를 성공적으로 실행합니다.

파트 2에서 이어지는 내용: 실제 DRF 테스트 사용 사례

다음 섹션에서는 다음을 다룰 예정입니다:

  • Blog + Writer + Category + SocialMediaMeta 샘플 모델
  • 중첩 직렬화기
  • 외래키 생성 테스트
  • 시그널 및 역관계 테스트
  • 오류‑검증 테스트
  • 중첩 JSON 구조 테스트
  • 인증된 요청 테스트
Back to Blog

관련 글

더 보기 »