From 747245d9acd46ce11c7b590f6f2e9315c82aad36 Mon Sep 17 00:00:00 2001 From: pricelees Date: Thu, 16 Oct 2025 10:25:31 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20k6=20=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 초기 셋업 데이터 로드는 로컬에서 받아오도록 수정 - tag 추가로 ID별 구분이 아닌 API별 구분 집계 --- test-scripts/common.js | 8 ++++---- test-scripts/create-reservation-scripts.js | 24 +++++++++++++--------- test-scripts/create-schedule-scripts.js | 9 ++++---- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/test-scripts/common.js b/test-scripts/common.js index 3f3e6098..05e3a54d 100644 --- a/test-scripts/common.js +++ b/test-scripts/common.js @@ -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 } }; } diff --git a/test-scripts/create-reservation-scripts.js b/test-scripts/create-reservation-scripts.js index d5c26aca..c51e5aa5 100644 --- a/test-scripts/create-reservation-scripts.js +++ b/test-scripts/create-reservation-scripts.js @@ -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 diff --git a/test-scripts/create-schedule-scripts.js b/test-scripts/create-schedule-scripts.js index 35eb6a39..a698d3fd 100644 --- a/test-scripts/create-schedule-scripts.js +++ b/test-scripts/create-schedule-scripts.js @@ -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; }