모든 애플리케이션은 고유한 요구사항을 가지고 있으며 이에 애플리케이션의 특성에 맞는 다양한 시나리오를 시뮬레이션 할 필요가 있다. 따라서 성능 테스트는 단일 테스트로 한정되지 않으며 각 애플리케이션이 직면한 요구사항과 시나리오에 맞춰 다양하게 구성된다. 이번 포스팅에서는 성능 테스트를 진행할 때 염두해둬야할 테스트 유형들에 대해 간단하게 알아보고 k6를 사용해 테스트 스크립트를 작성해보고자 한다.
성능 테스트 도구 중 하나인 k6에 대해 정리해 놓은 글이 있으니 참고하면 좋을 듯 하다.
2023.12.29 - [Testing] - k6 - 성능 테스트 도구 (Performance Testing Tool)
< 목차 >
- 성능 테스트 유형
- Smoke testing
- Load testing
- Stress testing
- Spike testing
- Breakpoint testing
- Soak testing
1. 성능 테스트 유형
"성능 테스트"는 다양한 유형의 테스트들을 포괄하는 용어라고 보면 된다. Load testing, Stress testing, Spike testing 등 다양한 종류의 테스트를 아우르는 용어인 셈이다. 성능 테스트에는 어떠한 테스트들이 있는지 간략하게 훑어본 후 하나하나 자세히 살펴보도록 하자.
- Smoke testing
- 최소한의 부하로 짧은 시간 동안 애플리케이션의 기본 기능과 테스트 스크립트가 제대로 작동하는지를 검증한다.
- 기본 기능들이 정상적으로 작동하는지 확인하는 것이 목적이다.
- Load testing
- 다수의 사용자가 동시에 시스템에 접근하는 상황을 시뮬레이션 함으로써 애플리케이션의 성능을 평가한다.
- 일반적인 조건 하에서 애플리케이션이 어떻게 작동하는지 파악하는 것이 목적이다.
- Stress testing
- 애플리케이션에 평균 이상의 부하를 가하여 성능을 평가한다.
- Load testing과 유사하지만, 부하의 크기가 증가된 것이 주된 특징이다.
- Spike testing
- 애플리케이션에 예상치 못한, 매우 높은 부하를 갑자기 가하여 시스템의 급격한 부하 처리 능력과 복구 능력을 평가한다.
- 예기치 않은 트래픽 증가 상황을 시뮬레이션 하기에 적합한 테스트이다.
- Breakpoint testing
- 애플리케이션의 최대 부하 용량을 확인하기 위해 설계된 테스트이다.
- 애플리케이션의 한계점을 찾기 위해 부하를 점진적으로 증가시키면서 실행된다.
- Soak testing
- 애플리케이션이 장기간 지속되는 부하를 어떻게 견디는지 평가하기 위한 테스트이다.
- 애플리케이션의 내구성을 검증하고 장기간 발생할 수 있는 문제들을 식별하는 것이 목적이다.
2. Smoke testing
Smoke testing은 애플리케이션의 기본 기능을 검사하는 테스트이다. 애플리케이션이 제대로 작동하는지 빠르고 효과적으로 검증하는 용도이며 일반적으로 매우 짧은 시간 동안, 1~3명 정도의 가상 사용자(VUs)를 사용하여 최소한의 부하만으로 실행된다. 이러한 방식의 테스트는 낮은 처리량과 짧은 테스트 기간을 특징으로 하며, 주 목적은 테스트 스크립트와 애플리케이션이 예상대로 작동하는지를 확인하는데에 있다고 볼 수 있다.
다음은 k6를 사용하여 진행한 smoke testing 스크립트이다.
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
vus: 1,
duration: '30s',
};
export default function () {
http.get('https://test.k6.io');
sleep(1);
http.get('https://test.k6.io/contacts.php');
sleep(2);
http.get('https://test.k6.io/news.php');
sleep(2);
}
이 코드는 1명의 가상 사용자가 여러 웹 페이지에 접속하는 과정을 시뮬레이션 한 것이다. 테스트는 30초 동안 진행되었으며 애플리케이션에 최소한의 부하만을 가해 가장 기본적인 사용 사례를 검증하는데 중점을 두었다. 다시 한번 언급하지만, smoke testing의 주요 목적은 애플리케이션의 기본적인 동작 여부를 파악하는 것이다. 따라서 smoke testing은 복잡한 내용의 성능 테스트가 아니라 테스트 스크립트와 애플리케이션이 모두 정상적으로 작동하는지 확인하는 수준의 테스트라고 생각하면 된다.
Smoke testing의 성공은 애플리케이션이 추가적인 테스트를 진행할 준비가 되었음을 의미한다. 만약 smoke testing에서 문제가 발생했다면, 해당 문제에 대해서는 즉각적인 해결이 필요하다고 볼 수 있다. Smoke testing과 같은 테스트는 CI/CD 파이프라인에 통합되어 시스템을 정기적으로 모니터링하는 데에도 사용될 수 있으며 시스템에 거의 부하를 주지 않는다는 점에서 프로덕션 환경에서도 안전하게 실행될 수 있다.
3. Load testing
Load testing은 애플리케이션을 일반적인 부하 하에서 테스트하는 과정이다. 실제 서비스 중인 애플리케이션이라면 해당 애플리케이션의 성능을 실제와 유사한 조건 하에서 평가하는 것이라고 생각하면 된다. Load testing에서는 다수의 사용자가 동시에 시스템에 접근하는 상황을 모방하여 애플리케이션이 실제 사용 환경에서 어떻게 작동하는지를 평가한다. 또한 load testing에서 중요한 부분은 시간이 지남에 따라 나타나는 성능의 변화를 관찰하는 것이다. 몇 분간의 짧은 테스트로는 파악하기 어려운, 시간이 경과함에 따라 나타날 수 있는 문제들을 포착하기 위해 일반적으로 30분 이상의 duration을 갖고 지속된다. 이를 통해 애플리케이션이 장시간의 부하 하에서 어떠한 퍼포먼스를 보여주는지 파악할 수 있다.
다음은 k6를 사용하여 진행한 load testing 스크립트이다.
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
stages: [
{ duration: '5m', target: 100 }, // 5분 동안 사용자 수를 0에서 100까지 증가
{ duration: '30m', target: 100 }, // 30분 동안 사용자 수를 100으로 유지
{ duration: '5m', target: 0 }, // 5분 동안 사용자 수를 100에서 0으로 감소
],
};
export default function () {
http.get('https://test.k6.io');
sleep(1);
http.get('https://test.k6.io/contacts.php');
sleep(2);
http.get('https://test.k6.io/news.php');
sleep(2);
}
스크립트를 살펴보면 기존과 달리 "stages" 옵션이 추가된 것을 확인할 수 있다. stages 옵션을 통해 사용자 수를 점진적으로 증가시키거나 감소시킬 수 있으며 이를 통해 실제 사용자의 행동 패턴을 효과적으로 모방할 수 있다. Load testing을 진행하는 내내 애플리케이션에 일정한 부하를 가하는 것은 아니다. stages를 통해 단계별로 애플리케이션에 부하를 가하게 되며 첫 번째 stage에서는 원하는 값(target)에 도달할 때까지 부하를 증가시킨다. 그 후 일정 시간 동안 target 값을 유지한 다음, 마지막 stage에서는 다시금 부하를 감소시키게 된다.
Load testing은 애플리케이션을 배포하기 전에 필수적으로 수행되는 테스트이며 특히 인프라 변경이 있을 때마다 반복적으로 수행하는 것이 권장된다. 또한 최적의 결과를 얻기 위해 실제 프로덕션 환경(production environment)을 가능한 한 정확히 모방한 pre-production 환경에서 수행되는 것이 좋다.
4. Stress testing
Stress testing은 애플리케이션에 평균 이상의 부하를 가하는 테스트이다. 해당 테스트의 목적은 평소보다 무거운 부하 상황에서 애플리케이션의 성능을 평가하는데 있다. 얼핏 보면 load testing과 별 차이가 없어 보일 수 있지만, 적용되는 부하의 크기가 훨씬 크다는 점에서 주된 차이가 있다.
다음은 k6를 사용하여 진행한 stress testing 스크립트이다.
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
stages: [
{ duration: '5m', target: 1000 }, // load testing과 다른 target 설정
{ duration: '30m', target: 1000 },
{ duration: '5m', target: 0 },
],
};
export default function () {
http.get('https://test.k6.io');
sleep(1);
http.get('https://test.k6.io/contacts.php');
sleep(2);
http.get('https://test.k6.io/news.php');
sleep(2);
}
스크립트의 "stages" 옵션을 살펴보면 load testing과 유사하게 구성되어 있는 것을 확인할 수 있다. 하지만 stress testing에서는 target 값을 상향 조정해 평균 이상의 높은 부하 상황에서 애플리케이션이 어떻게 반응하는지 파악하는 것에 중점을 두었다.
5. Spike testing
Spike testing은 예기치 않은 사건이나 상황으로 인해 애플리케이션 사용자 수에 갑작스러운 증가가 발생하는 경우를 시뮬레이션하는 테스트이다. 일반적인 트래픽 수준을 크게 초과하는 사용자가 동시에 접속하는 상황을 가정하여, 애플리케이션이 이러한 갑작스런 부하 증가를 어떻게 처리하고 이후에 어떻게 복구하는지를 평가하는 것이다. 따라서 spike testing에서는 애플리케이션의 성능 한계를 넘어서는 높은 부하를 갑자기 가하고, 이후 부하를 급격히 줄이는 방식으로 시나리오가 구성된다.
다음은 k6를 사용하여 진행한 spike testing 스크립트이다.
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 10000 }, // 사용자 수의 급격한 증가를 시뮬레이션
{ duration: '1m', target: 0 }, // 매우 빠르게 발생
],
};
export default function () {
// 사용자들의 일반적인 사용 패턴과 다를 수 있다
http.get('https://test.k6.io');
sleep(1);
}
스크립트를 살펴보면 spike testing의 핵심은 급격한 부하의 증가와 감소라는 점을 확인할 수 있다. Duration과 target 값에서도 확인할 수 있듯이 짧은 시간 동안 stress testing에서 설정된 부하의 4~5배 이상에 해당하는 높은 부하를 가함으로써 애플리케이션이 갑작스런 부하 증가에 어떻게 대응하는지 파악하는 것이 spike testing의 주 목적이다. 이에 일반적인 상황에서 자주 수행되는 테스트는 아니며 특정 상황에서만 실행된다. 예를 들어 예상치 못한 이벤트나 마케팅, 캠페인 등으로 인해 사용자가 단시간에 급증할 것으로 예상되는 경우 spike testing을 수행하는 것은 매우 유용할 수 있다.
혹여 spike testing을 진행하는 동안 시스템이 정상적으로 작동하지 못하는 상황에 직면하더라도 크게 놀랄 필요는 없다. 갑작스레 매우 높은 부하가 가해지는 예상치 못한 상황을 가정한 테스트이기 때문에 시스템이 비정상적으로 작동할 것이라는 사실은 인지하고 있어야 한다. 더 중요한 것은 spike testing 결과를 통해 시스템이 충돌한 후에도 자동으로 복구가 가능한지, 아니면 엔지니어의 개입을 필요로 하는지 등을 파악하는 것이다. 테스트 결과를 통해 얻은 이러한 정보들은 애플리케이션의 복원력, 안정성 같은 부분들을 평가하는데 중요한 역할을 한다.
6. Breakpoint testing
Breakpoint testing은 애플리케이션의 한계와 복구 능력을 평가하기 위한 테스트이다. 해당 테스트의 목적은 애플리케이션이 얼마나 많은 트래픽을 처리할 수 있는지, 언제 한계에 도달하는지를 파악하는 것이다. 따라서 breakpoint testing에서는 점진적으로 부하를 증가시키면서 애플리케이션이 붕괴되기 시작하는 지점을 찾게 된다.
다음은 k6를 사용하여 진행한 breakpoint testing 스크립트이다.
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
stages: [
{ duration: '2h', target: 1000000000 }, // 애플리케이션이 절대로 처리할 수 없을 정도로 설정
],
};
export default function () {
http.get('https://test.k6.io');
sleep(1);
}
스크립트를 살펴보면 단일 stage로 구성되어 있는 것을 확인할 수 있다. 애플리케이션이 감당할 수 없을 정도의 target을 설정하고 점진적으로 긴 시간 동안 부하를 가하는 시나리오를 구성한 것이다. 이러한 접근으로 어느 시점부터 애플리케이션의 성능 저하가 시작되는지, 그리고 최종적으로 언제 시스템이 무너지는지를 파악할 수 있다.
Breakpoint testing은 load testing과 stress testing을 성공적으로 완료한 후에 실행하는 것이 적합하다. 반드시 순서를 지켜야만 하는 것은 아니지만, 단계를 밟아가면서 진행한다면 시스템이 일반적인 조건과 고부하 상황에서 어떻게 작동하는지 그리고 한계는 어디인지를 이해하는데 도움이 될 것이다. 또한 breakpoint testing을 진행할 때는 애플리케이션을 모니터링하면서 사용자 요청에 대한 응답 시간이 지나치게 길어지거나 예상치 못한 문제가 자주 발생하는 시점을 알아채는 것이 중요하다. 이러한 정보들은 애플리케이션의 한계를 파악하고 시스템의 내구성과 안정성을 평가하는데 도움이 되기 때문이다.
7. Soak testing
Soak testing은 애플리케이션이 장기간에 걸친 지속적인 부하를 어떻게 견뎌내는지 평가하는데 중점을 둔 테스트이다. 한 시간 동안 부하를 견딜 수 있다고 해서 그것이 하루 혹은 그 이상을 견딜 수 있다는 것을 의미하지는 않는다. 장기간 동안 지속되는 부하는 애플리케이션에 잠재적인 문제들을 발생시킬 여지가 있다. 예를 들어 메모리 누수 같은 문제는 시간이 지남에 따라 발생하는 문제들 중 하나이며, 이는 시스템의 성능을 저하시키고 결국 시스템 안정성에까지 영향을 미칠 수 있다. Soak testing은 load testing과 비슷한 stage들로 시나리오가 구성되지만 아주 오랜 시간 동안 지속적인 부하를 주는 단계가 존재한다는 것이 주된 차이점이다.
다음은 k6를 사용하여 진행한 soak testing 스크립트이다.
// 추가 옵션
export const options = {
stages: [
{ duration: '5m', target: 100 },
{ duration: '24h', target: 100 }, // load testing과 다른 duration 설정
{ duration: '5m', target: 0 },
],
};
export default function () {
http.get('https://test.k6.io');
sleep(1);
http.get('https://test.k6.io/contacts.php');
sleep(2);
http.get('https://test.k6.io/news.php');
sleep(2);
}
스크립트를 살펴보면 "stages" 옵션에서 두 번째 단계를 '24h'로 설정한 것을 볼 수 있다. 이는 애플리케이션에 장기간 지속적인 부하를 가하는 상황을 시뮬레이션하기 위함이며 이를 통해 애플리케이션이 장기간의 부하를 견딜 수 있는지, 시간이 지남에 따라 발생하는 문제들은 어떤 것들이 있는지 등을 파악할 수 있다.
Soak testing은 load testing이 성공적으로 완료된 후에 수행하는 것이 적합하며, 애플리케이션의 장기적인 성능과 안정성을 평가하고 장기간의 부하 하에서 발생할 수 있는 잠재적인 문제들을 식별할 수 있다는 점에서 의미가 있다.
'Testing' 카테고리의 다른 글
k6 - 성능 테스트 도구 (Performance Testing Tool) (0) | 2023.12.29 |
---|