factory-boy와 Faker로 실제 같은 테스트 데이터 대량 생성하기

테스트 코드의 품질과 생산성을 극적으로 높이는 factory-boy와 Faker 라이브러리로 실제 데이터와 유사한 '살아있는' 테스트 데이터를 대량으로 효율적으로 생성하는 방법

테스트 데이터 생성의 문제점

  • 유지보수 어려움: 모델 필드 변경 시 모든 테스트 코드 수정 필요

  • 다양성 부족: 단순한 고정 데이터로는 현실적인 엣지 케이스 커버 불가

  • 가독성 저하: 데이터 생성 코드가 테스트 핵심 로직을 방해

기본 설정 및 Factory 정의

pip install factory-boy Faker

UserFactory 예시

import factory
from faker import Faker
from django.contrib.auth import get_user_model

fake = Faker('ko_KR')

class UserFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = get_user_model()
        django_get_or_create = ('username',)

    first_name = factory.Faker('first_name', locale='ko_KR')
    last_name = factory.Faker('last_name', locale='ko_KR')
    username = factory.LazyAttribute(lambda o: f'{o.first_name}{o.last_name}_{fake.lexify("????")}')
    email = factory.Faker('email')
    password = factory.PostGenerationMethodCall('set_password', 'defaultpassword123')

핵심 Factory 기능

SubFactory vs LazyAttribute

  • SubFactory: 관계된 객체를 실제로 DB에 생성하여 연결

  • LazyAttribute: 자신의 다른 속성값을 참조하여 동적으로 값 생성

Sequence로 유니크 필드 처리

post_generation으로 M2M 필드 처리

Trait로 팩토리 변형

테스트 코드에서 Factory 활용

실무 팁

create vs build 전략

  • create(): DB에 실제 레코드 저장, 객체 생성 후 DB 조회 필요한 테스트용

  • build(): 파이썬 객체만 생성, API request body 생성용으로 속도 빠름

재현 가능한 테스트

Factory 파일 관리

  • 각 앱 디렉토리에 factories.py 파일로 관리

  • 공용 Factory는 corecommon 앱에 모아서 관리

Last updated