[230215 - TIL] 테스트 데이터 생성 성능개선

Dongwoo Kim·2023년 2월 16일
0

TIL / WIL

목록 보기
82/113

1. 개요

django 테스트 코드를 만들기위해 초기 테스트 데이터를 생성하는데 꽤많은 시간을 소비하는 일이 발생했다. 때문에 어떻게하면 데이터 생성에 시간을 많이 소비하지않고 테스트를 할 수 있을지 여러가지 방법을 고민해보았다.


2. 기존 문제점

테스트에 사용할 데이터가 너무 많아서 테스트할 때마다 초기 DB 생성시 너무 오래걸림

ex) 테스트 데이터 생성하는데 1분넘게 걸림 → 코드 한줄 작성하고 동작 확인하는데 1분씩기다려야함


3. 찾아본 방법

1. 테스트 DB를 계속 유지해서 다시 테스트를 실행할 때 생성하지 않도록 할 수 없을까?

—keepdb 커맨드 추가시 (python [manage.py](http://manage.py) test myapp —keepdb) 해당 테스트에서는 DB를 유지할 수 있음

But 내가 원하는 것은 테스트 종료 후 다시 테스트를 진행해도 DB를 유지하는 것 → X

2. 기존의 DB를 가지고 따로 테스트 역할의 함수를 만들까?

test를 따로 실행하는 것이 아니라 기존 프로젝트를 실행시키고 test용 함수를 만들고 기존 DB로 함수를 실행한 결과값을 비교하면 DB를 생성하는 시간을 아낄수 있다라는 취지

But 테스트를 진행할 때마다 DB 상태가 달라질 것이기 때문에 비교 결과값도 달라질 수 있음 + 이전처럼 직접 손으로 테스트하던 것과 다를게 뭐지?

3. 그냥 DB를 빨리 생성할 수 있는 방법은 없을까?

회사에서는 그렇게 방법를 못찾아서 답답했는데 집가는길에 아이디어가 생각남

데이터를 각각 하나씩 생성하는 것이 아니라 한번에 생성하는 것!

  • 기존 코드
    상품 데이터 하나씩 save()
    → save()할때마다 CREATE 쿼리 발생
    → 상품이 많아질 수록 시간이 매우 오래 걸린다
	for i, obj in enumerate(json.loads(open(os.path.join(BASE_DIR, 'promotion/test_data/product_test_queryset.json')).read())):
		serializer = product_test__Serializer(data=obj)
		if serializer.is_valid():
        	serializer.save()
			if i % 200 == 0:
				print(obj["product_no"])
  • 개선 코드
    상품 데이터로 오브젝트를 만들고 리스트에 누적
    → 오브젝트 리스트로 bulk_create() 진행
    → 하나의 쿼리로 모든 상품 오브젝트 저장 가능!
	product_obj_list = []
	for i, obj in enumerate(json.loads(open(os.path.join(BASE_DIR, 'promotion/test_data/product_test_queryset.json')).read())):
		product_obj = product(**obj)
		product_obj_list.append(product_obj)
	product.objects.bulk_create(product_obj_list)

3. 개선 후 성능 비교

기존 : 3200여개 상품 데이터 저장하는데 34초

개선후 : 단 0.97초

profile
kimphysicsman

0개의 댓글