refactor: k6 스크립트 수정

- 초기 셋업 데이터 로드는 로컬에서 받아오도록 수정
- tag 추가로 ID별 구분이 아닌 API별 구분 집계
This commit is contained in:
이상진 2025-10-16 10:25:31 +09:00
parent e6cfd7b68b
commit 747245d9ac
3 changed files with 22 additions and 19 deletions

View File

@ -22,7 +22,7 @@ export function parseIdToString(response) {
}
export function maxIterations() {
const maxIterationsRes = http.get(`${BASE_URL}/tests/max-iterations`)
const maxIterationsRes = http.get(`http://localhost:8080/tests/max-iterations`)
if (maxIterationsRes.status !== 200) {
throw new Error('max-iterations 조회 실패')
}
@ -57,7 +57,7 @@ export function login(account, password, principalType) {
password: password,
principalType: principalType
})
const params = { headers: { 'Content-Type': 'application/json' } }
const params = { headers: { 'Content-Type': 'application/json' }, tags: { name: '/auth/login' } }
const loginRes = http.post(`${BASE_URL}/auth/login`, loginPayload, params)
@ -78,7 +78,7 @@ export function login(account, password, principalType) {
}
}
export function getHeaders(token) {
export function getHeaders(token, endpoint) {
const headers = {
'Content-Type': 'application/json',
};
@ -87,5 +87,5 @@ export function getHeaders(token) {
headers['Authorization'] = `Bearer ${token}`;
}
return { headers: headers };
return { headers: headers, tags: { name: endpoint } };
}

View File

@ -15,10 +15,13 @@ export const options = {
scenarios: {
user_reservation: {
executor: 'ramping-vus',
startVUs: 1500,
startVUs: 0,
stages: [
{ duration: '10m', target: 1500 },
{ duration: '1m', target: 0 }
{ duration: '3m', target: 500 },
{ duration: '2m', target: 1000 },
{ duration: '2m', target: 1500 },
{ duration: '3m', target: 1500 },
{ duration: '3m', target: 0 },
]
}
},
@ -92,7 +95,8 @@ export default function (data) {
while (searchTrial < 5) {
storeId = randomItem(stores).storeId
targetDate = randomDayBetween(1, 7)
const res = http.get(`${BASE_URL}/stores/${storeId}/schedules?date=${targetDate}`)
const params = getHeaders(accessToken, "/stores/${storeId}/schedules?date=${date}")
const res = http.get(`${BASE_URL}/stores/${storeId}/schedules?date=${targetDate}`, params)
const result = check(res, {'일정 조회 성공': (r) => r.status === 200})
if (result !== true) {
continue
@ -118,7 +122,7 @@ export default function (data) {
const randomThemesForFetchDetail = extractRandomThemeForFetchDetail(themesByStoreAndDate)
randomThemesForFetchDetail.forEach(id => {
http.get(`${BASE_URL}/themes/${id}`)
http.get(`${BASE_URL}/themes/${id}`, getHeaders(accessToken, "/themes/${id}"))
sleep(10)
})
})
@ -137,11 +141,11 @@ export default function (data) {
let isScheduleHeld = false
group(`일정 Holding 및 테마 정보 조회 -> 예약 과정중 첫 페이지의 작업 완료`, function () {
const holdRes = http.post(`${BASE_URL}/schedules/${availableScheduleId}/hold`, null, getHeaders(accessToken))
const holdRes = http.post(`${BASE_URL}/schedules/${availableScheduleId}/hold`, null, getHeaders(accessToken, "/schedules/${id}/hold"))
const body = JSON.parse(holdRes.body)
if (check(holdRes, {'일정 점유 성공': (r) => r.status === 200})) {
const themeInfoRes = http.get(`${BASE_URL}/themes/${selectedThemeId}`)
const themeInfoRes = http.get(`${BASE_URL}/themes/${selectedThemeId}`, { tag: { name: "/themes/${id}"}})
selectedThemeInfo = parseIdToString(themeInfoRes).data
isScheduleHeld = true
} else {
@ -160,7 +164,7 @@ export default function (data) {
group(`예약 정보 입력 페이지`, function () {
let userName, userContact
group(`회원 연락처 조회`, function () {
const userContactRes = http.get(`${BASE_URL}/users/contact`, getHeaders(accessToken))
const userContactRes = http.get(`${BASE_URL}/users/contact`, getHeaders(accessToken, "/users/contact"))
if (!check(userContactRes, {'회원 연락처 조회 성공': (r) => r.status === 200})) {
throw new Error("회원 연락처 조회 과정에서 예외 발생")
@ -191,7 +195,7 @@ export default function (data) {
requirement: requirement
})
const pendingReservationCreateRes = http.post(`${BASE_URL}/reservations/pending`, payload, getHeaders(accessToken))
const pendingReservationCreateRes = http.post(`${BASE_URL}/reservations/pending`, payload, getHeaders(accessToken, "/reservations/pending"))
const responseBody = parseIdToString(pendingReservationCreateRes)
if (pendingReservationCreateRes.status !== 200) {
@ -229,7 +233,7 @@ export default function (data) {
let isConfirmed = false
while (trial < 2) {
sleep(30)
const confirmOrderRes = http.post(`${BASE_URL}/orders/${reservationId}/confirm`, payload, getHeaders(accessToken))
const confirmOrderRes = http.post(`${BASE_URL}/orders/${reservationId}/confirm`, payload, getHeaders(accessToken, "/orders/${reservationId}/confirm"))
if (check(confirmOrderRes, {'예약 확정 성공': (r) => r.status === 200})) {
isConfirmed = true

View File

@ -1,17 +1,17 @@
import http from 'k6/http';
import {check, sleep} from 'k6';
import {check} from 'k6';
import exec from 'k6/execution';
import {BASE_URL, getHeaders, login, parseIdToString} from "./common.js";
import {randomIntBetween} from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';
const TOTAL_ITERATIONS = 85212;
const TOTAL_ITERATIONS = 200000;
export const options = {
scenarios: {
schedule_creation: {
executor: 'shared-iterations',
vus: 263,
vus: 100,
iterations: TOTAL_ITERATIONS,
maxDuration: '30m',
},
@ -97,7 +97,7 @@ function createSchedule(storeId, accessToken, schedule) {
time: schedule.time,
themeId: schedule.themeId,
});
const params = getHeaders(accessToken)
const params = getHeaders(accessToken, "/admin/stores/${id}/schedules")
const res = http.post(`${BASE_URL}/admin/stores/${storeId}/schedules`, payload, params);
const success = check(res, {'일정 생성 성공': (r) => r.status === 200 || r.status === 201});
@ -105,7 +105,6 @@ function createSchedule(storeId, accessToken, schedule) {
if (!success) {
console.error(`일정 생성 실패 [${res.status}]: 매장=${storeId}, ${schedule.date} ${schedule.time} (테마: ${schedule.themeId}) | 응답: ${res.body}`);
}
sleep(5)
return success;
}