[TIL] JMeter 으로 API 테스트하기

YJin·2025년 7월 6일

[내배캠 Spring 6기_TIL]

목록 보기
51/56

들어가기 전

그동안은 단위/통합 테스트로 JUnit이나 Postman만 사용해왔지만, 이번엔 기능 부하 테스트가 필요해져서 테스트 툴을 처음으로 사용해보게 되었다.

테스트 툴은 nGrinder, k6, Locust 등 여러가지가 있지만, 우선은 가장 많이 쓰이는 툴 중 하나인 JMeter 를 선택했다.


JMeter는 Apache 재단에서 공식적으로 사용하는 Java 기반 오픈소스 테스트 도구다.
출시된 지 오래된 만큼 자료나 플러그인 종류가 다양해 확장성이 좋다.

CLI, GUI 두 가지 인터페이스를 지원하며 처음이니 사용하기 편리한 GUI를 사용해봤다.

설치 및 실행

🔗Apache 공식 사이트


1. 사이트에 들어가서 압축 파일 (tgz or zip) 다운로드
-만약 Java 가 설치되어 있지 않다면 JMeter 버전에 맞는 Java 버전 설치 필요
2. 원하는 경로에 압축 풀기
3. cmd에서 apache-jemeter 폴더 내 bin으로 이동
4. ./jmeter.bat 입력해서 실행 (윈도우 기준)
- 맥북, 리눅스 환경에선 ./jmeter.sh 실행


정상적으로 실행 시 JMeter GUI 창이 나타난다.



주요 용어 정리

Test Plan

  • JMeter에서 실행할 전체 테스트 시나리오의 최상위 단위.
  • 하나의 Test Plan 안에 여러 Thread Group, Sampler, Controller 등을 포함, 테스트 환경 변수와 설정도 함께 정의.

Thread Group

  • 하나의 테스트 시나리오
  • 누가, 얼마나, 몇 번 행동할지
  • 가상의 사용자(스레드) 수, Ramp-Up 시간, 반복 횟수 등 부하 발생 패턴을 정의.

Sampler

  • 실제 요청을 전송
  • 무슨 행동을 할지
  • HTTP, JDBC, FTP 등 다양한 프로토콜 지원.
  • 예: HTTP Request Sampler로 API 호출, JDBC Sampler로 DB 쿼리 실행.

Logic Controller

  • Sampler 실행 순서나 조건을 제어하는 요소.
  • 예: Loop Controller로 요청 반복, If Controller로 조건 분기, Transaction Controller로 여러 요청을 하나의 측정 단위로 묶음.

Config Element

  • 테스트 플랜 내에서 Sampler나 Controller가 참조할 공통 설정을 제공.
  • 예: HTTP Request Defaults로 기본 URL/포트 지정, CSV Data Set Config로 외부 CSV 데이터 변수 로드

기타 용어

여기서부터는 테스트를 세세하게 컨트롤하고 싶을 때 알아두면 좋은 용어들이다.

Timer

  • 요청 간 지연 시간을 설정해 현실적인 부하 패턴을 시뮬레이션.
  • 예: Uniform Random Timer로 200~500ms 랜덤 대기.

Assertion

  • 응답이 기대한 조건을 만족하는지 검증.
  • 예: 응답 코드 200인지 확인, 응답 본문에 특정 문자열 포함 여부 검사.

Pre-Processor

  • Sampler 실행 전에 필요한 데이터 가공이나 변수 설정.

Post-Processor

  • Sampler 실행 후 응답 데이터를 파싱하거나 변수로 저장.

Listener

  • 테스트 실행 결과를 시각화하거나 파일로 저장.

Controller (상위 개념)

  • Logic Controller와 Sampler를 포함해 실행 흐름을 제어하는 요소.
  • 예: Simple Controller로 요청 그룹화, Module Controller로 다른 구성 불러오기.

Variable

  • ${변수명} 형식으로 참조하는 동적 값.
  • CSV, 스크립트, Property 등에서 주입 가능.

Property

  • CLI 실행 시 -J 옵션으로 전달하는 전역 속성.
  • 예: -Jusers=100.

Ramp-Up Period

  • Thread Group 내 모든 스레드가 시작되는 데 걸리는 시간.
  • 예: 100스레드, 60초 Ramp-Up → 0.6초마다 1명씩 시작.

Throughput

  • 단위 시간당 처리 요청 수.
  • 보통 TPS(Transactions per Second)로 표시.

Loop Count

  • 각 스레드가 Sampler를 반복하는 횟수.
  • 예: 10이면 사용자 1명당 10번 요청 실행.



테스트 설정

1. 테스트 시나리오

시나리오: 로그인 API 부하 테스트

  • 가상 사용자 수: 1000명
  • Ramp-Up: 1초 → 1초 안에 1000명 모두 시작
  • Loop Count: 3회 → 각 사용자가 시나리오(로그인 요청)를 3번 반복
  • 아이디, 패스워드 정보는 csv로 준비



2. 테스트 준비

로그인 데이터 CSV Config

각 회원 로그인에 필요한 아이디 정보를 CSV 파일로 불러와서 사용할 예정이다.

Test Plan 우클릭 - Add - Config Element - CSV Data Set Config

Filename

  • 불러올 CSV 파일 경로를 지정
  • 경로명에 한글이 포함되면 실행 오류 발생할 수 있음

File encoding

  • CSV 파일의 문자 인코딩 방식
  • UTF-8로 설정 시 한글/영문 데이터 모두 처리 가능

Variable Names (comma-delimited)

  • CSV의 각 컬럼명을 지정
  • 지정한 이름이 JMeter 변수명으로 사용됨
  • 컬럼이 여러 개인 경우 순서대로 콤마로 구분해서 나열, 정확한 컬럼명을 써야하며 공백 넣기X (예: email,password,name)
  • 예: email → Sampler에서 ${email}로 참조

Ignore first line

  • True면 CSV 첫 번째 줄(헤더)을 데이터로 쓰지 않고 건너뜀.
  • 첫 줄을 헤더로 간주하고 두 번째 줄부터 읽음.

Delimiter

  • CSV 컬럼 구분자 설정 (CSV 파일 저장 시 설정 가능)
  • 예: , → 쉼표로 컬럼 구분.

Sharing mode

  • CSV 데이터를 여러 스레드가 어떻게 공유할지 지정.
  • All threads → 모든 스레드가 같은 데이터 순서를 공유.
  • 다른 옵션: Current thread(각 스레드가 독립적으로 읽음), Current thread group 등.

현재 설정 동작

  • CSV에서 email 컬럼 데이터를 첫 줄을 제외하고 순서대로 읽음.
  • 모든 스레드가 같은 순서로 데이터를 소비하며, EOF에 도달하면 처음부터 반복.
  • ${email} 변수로 Sampler에서 사용 가능.



User Defined Variables

아이디 정보는 CSV 파일로 받아오고, 비밀번호는 동일한 값을 쓰므로 User Defined Variables로 설정해준다.

  • 공통 로그인 비밀번호, API 키, 환경별 공통 URL 등 고정값을 지정 가능
  • 여러 Thread Group에서 동일 값 참조 가능.

Test Plan 우클릭 - Add - Config Element - User Defined Variables

변수 정의 표 (하단에 Add 로 추가)

  • Name

    • 변수명. ${변수명} 형태로 Sampler, Config Element, Assertion 등에서 참조 가능.
    • 예: email, password.
  • Value

    • 해당 변수의 값.
    • 예: password.

동작 방식

  • Test Plan 실행 시 전역 변수로 로드됨.
  • ${변수명} 형식으로 참조 가능.
  • CSV Data Set Config보다 우선순위가 낮음 → 같은 이름의 변수가 CSV에서 로드되면 CSV 값이 덮어씀.
  • 주로 모든 스레드·시나리오에서 동일하게 사용할 고정 값을 정의할 때 사용.



스레드 그룹

로그인 시나리오(스레드 그룹) 테스트 시 최대 몇명, 몇초에 걸쳐서, 몇번 반복 실행할 건지 정의해준다.

Test Plan 우클릭 - Add - Threads(Users) - Thread Group

Action to be taken after a Sampler error

  • Continue: 오류 발생 시 다음 요청 계속 실행.
  • Start Next Thread Loop: 현재 루프 중단, 다음 루프로 이동.
  • Stop Thread: 해당 스레드 종료.
  • Stop Test: 전체 테스트 정상 종료.
  • Stop Test Now: 전체 테스트 즉시 종료.

Number of Threads (users)

  • 가상 사용자(스레드) 수를 설정.
  • 예: 1000 → 동시에 최대 1000명 사용자가 동작

Ramp-up period (seconds)

  • 설정한 스레드 수를 모두 시작시키는 데 걸리는 시간(초).
  • 예: 1초 → 1000명이 1초 안에 모두 시작.

Loop Count / Infinite

  • 각 스레드가 시나리오를 반복 실행하는 횟수.
  • 예: 3 → 1명당 시나리오 3회 실행.
  • Infinite 체크 시 무한 반복.

Same user on each iteration

  • 체크 시 각 반복마다 같은 사용자 세션/데이터 사용.

Delay Thread creation until needed

  • 필요할 때만 스레드를 생성하여 메모리 사용량 절약.

Specify Thread lifetime

  • 스레드의 총 실행 시간과 시작 지연을 지정.

    • Duration: 스레드가 실행되는 총 시간(초).
    • Startup delay: 테스트 시작 후 스레드 시작까지의 지연(초).

현재 예시 설정 동작

  • 가상 사용자 1000명, 1초 안에 모두 시작.
  • 각 사용자는 시나리오를 3회 반복.
  • 스레드는 필요할 때만 생성되며, Sampler 오류 시 계속 진행.



컨트롤러 추가

복잡한 조건이나 반복 없이 스레드(유저) 당 로그인 요청을 한번만 할 것이므로 Once Only Controller를 추가해준다.

Thread 그룹 우클릭 - Add - Logic Controller - Once Only Controller

컨트롤러 종류

Once Only Controller

  • 각 스레드에서 하위 요소를 한 번만 실행.
  • 보통 로그인처럼 한 번만 수행해야 하는 작업에 사용.

Simple Controller

  • Sampler나 하위 Controller를 그룹화하는 용도 (폴더)
  • 기능적 제어 없이 Test Plan 정리·구조화에 사용.

Loop Controller

  • 하위 요소들을 지정한 횟수만큼 반복 실행.
  • 예: Loop Count=5 → 안에 있는 Sampler 전부 5번 실행.

While Controller

  • 주어진 조건이 참인 동안 반복 실행.
  • 조건식에 JMeter 변수나 함수 사용 가능.
  • 예: ${loginSuccess} == "false" → 로그인 성공할 때까지 반복.

If Controller

  • 조건이 참일 때만 하위 요소 실행.
  • 예: 응답 값이 특정 문자열 포함 시 다음 Sampler 실행.



샘플러 추가

필요한 요청 종류에 맞는 샘플러를 선택하면 된다. 지금은 API 테스트이므로 샘플러에서 HTTP Request를 추가해준다.

추가 후 테스트 하려는 API 스펙에 맞게 설정해주면 된다.

Web Server

  • Protocol: http로 설정.
  • Server Name or IP: 서버 주소
  • Port Number: 서버 포트 (예: 8080)

HTTP Request

  • Method: POST
  • Path: /auth/signin → 로그인 API 엔드포인트.

Body Data

  • 전송할 POST 요청 본문 (json)

CSV 파일 사용 시

{
  "email": "${email}",
  "password": "${password}"
}
  • ${변수명} 으로 변수 사용
  • 예: User Defined Variables나 CSV Data Set Config에서 로드

스레드 넘버 사용 시

{
  "email": "test${__threadNum}@email.com",
  "password": "${password}"
}
  • 스레드 넘버는 1부터 시작
  • 테스트 설정 중 스레드 넘버를 사용할 수 있는 방법을 찾아서 실제 테스트에선 이 요청 바디를 사용했다.
  • test1@email.com, test2@email.com ... 처럼 아이디가 간단하다면 CSV 로드보다 스레드 넘버를 사용하는 게 더 편리하다.

현재 예시 설정 동작

  • 스레드마다 고유한 email 값을 생성해 로그인 요청을 보냄.
  • password 값은 변수에서 불러옴.
  • HTTP POST 방식으로 /auth/signin 엔드포인트에 JSON 바디를 전송.



리스너 추가

리스너에서는 테스트 결과를 수집/요약 해주며, 만약 리스너가 없다면 이전의 테스트 결과는 수집되지 않으므로 테스트 전에 리스너가 추가되어 있는지 한번 확인해준다.

기본 제공 리스너 외에도 플러그인을 추가해서 시각적으로 편리하게 테스트를 확인할 수 있다.
TPS, 응답 시간 등을 그래프로 확인하기 위해jp@gc 플러그인을 추가해준다.

플러그인 설치법

참고 사이트 - https://devmango.tistory.com/40

필요한 리스너까지 추가하고나면 이렇게 테스트 설정이 완료된다.



3. 테스트 실행

상단의 녹색 버튼으로 테스트를 실행시킬 수 있다.
실행 중에도 리스너에서 실시간으로 결과를 확인할 수 있다.



4. 테스트 결과

TPS


응답 속도

TPS는 일정 시간 이후 일정하게 유지되고, 응답 속도는 점점 증가하는 것을 확인할 수 있다.



5. 테스트 저장

JMeter는 종료하면 생성한 테스트 플랜이 날아가므로 File - Save Test Plan as로 테스트 플랜 파일(jmx)를 저장해주어야 한다.

나중에 테스트 시 저장했던 jmx 파일을 불러와 테스트를 이어가면 된다.



profile
백엔드 개발도 락이다

0개의 댓글