Trawling
발견 출처 dev.to/발행

API Performance Testing: How to Design Realistic Tests

API 성능 테스트: 현실적인 테스트 설계 방법

성능 테스트의 종류(Load, Stress, Soak, Spike, Volume, Scalability)를 정리하고, 단순히 요청을 많이 보내는 것이 아니라 실제 사용자 행동을 모사하는 테스트 설계법을 다룹니다. 비즈니스 요구사항에서 목표 RPS를 역산하는 방법, 외부 서비스 목킹 기준, 프로덕션과 유사한 테스트 환경 구성, 평가 지표까지 실무 관점에서 설명합니다.

본문

성능 테스트는 릴리스 전에 애플리케이션이 예상 부하를 견딜 수 있는지 확인하는 비기능 테스트이지만, 잘못 설계되면 오히려 잘못된 결론을 이끌어냅니다. 저자는 이 글에서 성능 테스트 이론을 반복하는 대신, 현실적인 테스트를 어떻게 설계하는지에 초점을 맞춥니다.

성능 테스트의 6가지 유형

Load 테스트는 예상된 정상 트래픽에서 응답 시간·에러율·리소스 사용량이 허용 범위인지 검증합니다. Stress 테스트는 한계를 넘는 부하를 가해 CPU, 메모리, DB 커넥션, 스레드가 고갈될 때 어디서 성능이 저하되거나 실패하는지 파악합니다. Endurance(Soak) 테스트는 장시간 지속 부하로 메모리 누수나 커넥션 누수 같은 문제를 찾고, Spike 테스트는 급격한 트래픽 증가 후 회복 능력을 봅니다. Volume 테스트는 대량 데이터 처리(쿼리, 임포트, 배치 작업)를, Scalability 테스트는 리소스 추가 시 확장 효율을 검증합니다. 저자는 유형별로 별도 테스트를 만들 필요 없이 같은 시나리오의 동시 사용자 수·지속 시간·요청률만 바꿔 재사용할 수 있다고 조언합니다.

실제 사용자 경로 모사하기

무작위로 엔드포인트에 요청을 쏘는 것은 실제 병목을 알려주지 않습니다. 이커머스 예시에서 저자는 '상품 검색 → 장바구니 담기 → 체크아웃 → 결제'라는 전체 플로우를 프론트엔드가 호출하는 것과 같은 순서로 호출하도록 설계합니다. 사용자 유형별로 권한과 사용 패턴이 다른 비즈니스 앱이라면 유형별 워크플로우를 각각 만듭니다. 여기에 세 가지 현실성 요소를 더합니다. 실제 사용자는 테스트만큼 빠르게 클릭하지 않으므로 작업 사이에 think time을 넣고, 모든 사용자가 같은 경로를 따르지 않으므로(둘러보기만 하거나 장바구니에 담고 나가는 사용자 포함) 복수의 경로를 시뮬레이션하며, 동시 접속이 한꺼번에 몰리지 않으므로 부하를 점진적으로 ramp up합니다.

목표 부하 산정하기

성공 기준을 먼저 정의해야 합니다. 저자의 예시는 '예상 부하 150 RPS, p95 < 400ms, p99 < 1s, 에러율 < 0.5%, 요구 처리량 유지, 큐·커넥션의 지속적 증가 없음'입니다. 수치 산정에는 두 가지 경로가 있습니다. 첫째, Grafana 같은 관측 도구의 과거 프로덕션 지표(피크 요청률, 동시 사용자, 주문량, CPU·메모리)를 보고 성장률에 안전 마진을 얹는 방법입니다. 둘째, 비즈니스 요구사항에서 역산하는 방법입니다. '2시간 피크 동안 주문 10,000건'이 목표라면 주문 한 건이 평균 20개 요청을 만든다고 가정할 때 200,000 요청 ÷ 7,200초 ≈ 28 RPS가 나옵니다. 단 이것은 완료된 주문 플로우만의 평균이므로, 브라우징·포기된 장바구니·백그라운드 요청과 불균등한 트래픽 분포를 고려해 추가 마진을 둬야 한다고 강조합니다.

외부 서비스와 테스트 환경

유료 API(LLM API 등)나 테스트 범위 밖의 외부 서비스는 WireMock 같은 도구로 대체해, 외부 서비스의 성능·레이트 리밋·가용성이 결과를 오염시키지 않게 합니다. 반대로 외부 통신 자체가 실제 성능의 핵심이면 포함하거나 별도로 테스트합니다. 환경은 프로덕션과 최대한 같아야 합니다. 앱 설정, CPU·메모리·스케일링 규칙, 그리고 특히 DB는 거의 빈 상태로 테스트하면 안 됩니다. 수백만 행에서 조인·정렬·인덱스·실행 계획·통계·캐시는 완전히 다르게 동작하므로 현실적인 데이터 볼륨이 필요합니다. Redis 캐시 설정 차이나 항상 warm한 캐시도 결과를 왜곡하고, 로컬 목은 실제 외부 서비스의 수십~수백 ms 네트워크 지연을 반영하지 못하므로 필요하면 지연을 시뮬레이션합니다. 마지막으로 부하 생성기 자체가 충분한 CPU·메모리·네트워크·커넥션을 갖춰야 하며, 그렇지 않으면 테스트 대상이 아니라 생성기가 병목이 됩니다.

결과 평가와 리포트

Load 테스트에서는 p95/p99 응답 시간, 에러율, 실제 처리한 처리량, CPU·메모리·DB 커넥션 풀 등 리소스 사용량을 봅니다. Stress 테스트에서는 부하를 올리며 응답 시간·에러율 변화와 포화 지점을 찾고, 부하가 내려간 뒤 회복되는지(재시작이 필요한지와 대비)도 관찰합니다. 최종 리포트는 평균 응답 시간 같은 단일 수치가 아니라, 발생시킨 부하와 지연·처리량·에러·리소스 사용률을 연결해 '기대를 충족하지 못한 이유'까지 설명해야 한다고 저자는 정리합니다.

원문: dev.to / 번역·요약: Trawling