소프트웨어 성능 테스트

소프트웨어 품질 보증에서 **성능 테스트**(performance testing)는 일반적으로 특정 작업 부하에서 시스템이 응답성 및 안정성 측면에서 어떻게 작동하는지 결정하기 위해 수행되는 테스트 방식이다. 또한 확장성, 신뢰성 및 리소스 사용과 같은 시스템의 다른 품질 속성을 조사, 측정, 검증 또는 확인하는 데 사용될 수도 있다. 성능 테스트는 성능 공학의 하위 집합으로, 시스템의 구현, 설계 및 아키텍처에 성능 표준을 구축하려는 컴퓨터 과학 실습이다.
# 테스트 유형

## 부하 테스트
부하 테스트는 가장 간단한 형태의 성능 테스트이다. 부하 테스트는 일반적으로 특정 예상 부하에서 시스템의 동작을 이해하기 위해 수행된다. 이 부하는 설정된 기간 내에 특정 수의 트랜잭션을 수행하는 응용 프로그램에 대한 예상 동시 사용자 수일 수 있다. 이 테스트는 모든 중요한 비즈니스 핵심 트랜잭션의 응답 시간을 알려준다. 데이터베이스, 웹 애플리케이션 서버 등도 테스트 중에 모니터링되며, 이는 응용 소프트웨어 및 소프트웨어가 설치된 하드웨어의 병목 현상을 식별하는 데 도움이 된다.
## 스트레스 테스트
스트레스 테스트는 일반적으로 시스템 내의 용량 상한을 이해하는 데 사용된다. 이러한 종류의 테스트는 극한 부하 측면에서 시스템의 견고성을 결정하기 위해 수행되며, 응용 프로그램 관리자가 현재 부하가 예상 최대치를 훨씬 초과할 경우 시스템이 충분히 작동하는지 여부를 결정하는 데 도움이 된다.
## 침투 테스트
침투 테스트, 즉 내구성 테스트는 일반적으로 시스템이 지속적인 예상 부하를 견딜 수 있는지 여부를 결정하기 위해 수행된다. 침투 테스트 중에 메모리 사용률이 모니터링되어 잠재적인 메모리 누수를 감지한다. 또한 중요하지만 종종 간과되는 것은 성능 저하, 즉 일정 기간 동안 지속된 활동 후 처리량 및 응답 시간이 테스트 시작 시와 같거나 더 좋은지 확인하는 것이다. 이는 본질적으로 상당한 부하를 시스템에 장기간 적용하는 것을 포함한다. 목표는 지속적인 사용 시 시스템이 어떻게 동작하는지 파악하는 것이다.
## 스파이크 테스트
스파이크 테스트는 매우 많은 수의 사용자가 생성하는 부하를 갑자기 늘리거나 줄이고 시스템의 동작을 관찰하여 수행된다. 목표는 성능이 저하되는지, 시스템이 실패하는지, 또는 부하의 극적인 변화를 처리할 수 있는지 여부를 결정하는 것이다.
## 분기점 테스트
분기점 테스트는 스트레스 테스트와 유사하다. 미리 정해진 실패 조건을 위해 시스템을 모니터링하면서 시간이 지남에 따라 점진적인 부하가 적용된다. 분기점 테스트는 시스템이 요구되는 사양 또는 서비스 수준 협약에 따라 작동할 최대 용량을 결정한다고 말할 수 있으므로 때로는 용량 테스트라고도 한다. 고정된 환경에 적용된 분기점 분석 결과는 필요한 하드웨어 측면에서 최적의 스케일링 전략 또는 클라우드 환경에서 스케일아웃 이벤트를 트리거해야 하는 조건을 결정하는 데 사용될 수 있다.
## 구성 테스트
부하 관점에서 성능을 테스트하는 대신, 시스템 구성 요소에 대한 구성 변경이 시스템의 성능 및 동작에 미치는 영향을 결정하기 위해 테스트가 생성된다. 일반적인 예는 부하 분산의 다양한 방법을 실험하는 것이다.
## 격리 테스트
격리 테스트는 성능 테스트에만 고유한 것은 아니지만 시스템 문제를 초래한 테스트 실행을 반복하는 것을 포함한다. 이러한 테스트는 종종 결함 도메인을 격리하고 확인할 수 있다.
## 인터넷 테스트
이는 페이스북, 구글, 위키백과와 같은 글로벌 응용 프로그램을 실제 대상 대륙에 배치된 부하 생성기(물리적 머신 또는 클라우드 VM)에서 성능 테스트하는 비교적 새로운 형태의 성능 테스트이다. 이러한 테스트는 성공적으로 실행되기 위해 엄청난 양의 준비와 모니터링이 필요하다.
# 성능 목표 설정
성능 테스트는 다양한 목적을 수행할 수 있다: * 시스템이 성능 기준을 충족함을 입증할 수 있다. * 어떤 시스템이 더 잘 작동하는지 찾기 위해 두 시스템을 비교할 수 있다. * 시스템 또는 작업 부하의 어떤 부분이 시스템 성능을 저하시키는지 측정할 수 있다. 많은 성능 테스트는 충분히 현실적이고 목표 지향적인 성능 목표를 설정하지 않고 수행된다. 비즈니스 관점에서 첫 번째 질문은 항상 "왜 성능 테스트를 하는가?"여야 한다. 이러한 고려 사항은 테스트의 사업 사례의 일부이다. 성능 목표는 시스템의 기술 및 목적에 따라 달라지지만, 항상 다음 중 일부를 포함해야 한다:
## 동시성 및 처리량
시스템이 어떤 형태의 로그인 절차를 통해 최종 사용자를 식별하는 경우 동시성 목표는 매우 바람직하다. 정의에 따르면 이는 시스템이 주어진 순간에 지원해야 하는 동시 시스템 사용자의 최대 수이다. 스크립트된 트랜잭션의 작업 흐름은 특히 반복적인 부분이 로그인 및 로그아웃 활동을 포함하는 경우 진정한 동시성에 영향을 미칠 수 있다. 시스템이 최종 사용자 개념을 가지고 있지 않은 경우, 성능 목표는 최대 처리량 또는 트랜잭션 속도를 기반으로 할 가능성이 높다.
## 서버 응답 시간
이는 한 시스템 노드가 다른 노드의 요청에 응답하는 데 걸리는 시간을 나타낸다. 간단한 예는 브라우저 클라이언트에서 웹 서버로의 HTTP 'GET' 요청일 것이다. 응답 시간 측면에서 이는 모든 부하 테스트 도구가 실제로 측정하는 것이다. 시스템의 모든 노드 간에 서버 응답 시간 목표를 설정하는 것이 적절할 수 있다.
## 렌더 응답 시간
부하 테스트 도구는 렌더 응답 시간을 측정하는 데 어려움이 있다. 일반적으로 '온 와이어' 활동이 없는 기간을 인식하는 것 외에는 노드 내에서 발생하는 일에 대한 개념이 없기 때문이다. 렌더 응답 시간을 측정하려면 일반적으로 기능 테스트 스크립트를 성능 테스트 시나리오의 일부로 포함해야 한다. 많은 부하 테스트 도구는 이 기능을 제공하지 않는다.
## 성능 사양
성능 사양(요구사항)을 자세히 설명하고 모든 성능 테스트 계획에 문서화하는 것이 중요하다. 이상적으로는 이는 시스템 개발 프로젝트의 요구사항 개발 단계에서, 즉 어떤 설계 노력 이전에 수행된다. 자세한 내용은 성능 공학을 참조하라. 그러나 성능 테스트는 사양에 대해 자주 수행되지 않는다. 예를 들어, 특정 사용자 집단에 대한 최대 허용 응답 시간이 무엇이어야 하는지에 대해 아무도 표현하지 않았을 것이다. 성능 테스트는 종종 성능 프로파일 튜닝 과정의 일부로 사용된다. 아이디어는 "가장 약한 고리"를 식별하는 것이다. 즉, 더 빠르게 응답하도록 만들면 전체 시스템이 더 빠르게 실행될 시스템의 일부가 불가피하게 존재한다. 시스템의 어떤 부분이 이 핵심 경로를 나타내는지 식별하는 것은 때때로 어려운 작업이며, 일부 테스트 도구에는 서버에서 실행되는 (에이전트) 계측 기능을 포함하거나 추가 기능을 제공하여 트랜잭션 시간, 데이터베이스 접근 시간, 네트워크 오버헤드 및 기타 서버 모니터를 보고하며, 이를 원시 성능 통계와 함께 분석할 수 있다. 이러한 계측 기능이 없으면 윈도우 작업 관리자를 통해 서버에서 성능 테스트가 얼마나 많은 CPU 부하를 생성하는지 확인해야 할 수도 있다(테스트 중인 시스템이 윈도우 시스템이라고 가정). 성능 테스트는 웹을 통해 수행될 수 있으며, 심지어는 인터넷 자체의 응답 시간이 지역에 따라 다르다는 점을 고려하여 다른 국가에서도 수행될 수 있다. 또한 내부적으로도 수행할 수 있지만, 라우터는 공용 네트워크에서 일반적으로 발생하는 지연을 도입하도록 구성해야 할 것이다. 시스템에 대한 부하는 현실적인 지점에서 도입되어야 한다. 예를 들어, 시스템 사용자 기반의 50%가 56K 모뎀 연결을 통해 시스템에 접근하고 나머지 절반이 T1을 통해 접근한다면, 부하 주입기(실제 사용자를 시뮬레이션하는 컴퓨터)는 동일한 혼합 연결을 통해 부하를 주입하거나(이상적) 동일한 사용자 프로필에 따라 이러한 연결의 네트워크 지연 시간을 시뮬레이션해야 한다. 피크 시간대에 시스템을 사용할 것으로 예상되는 최대 사용자 수를 명시하는 것이 항상 도움이 된다. 또한 최대 허용 95백분위 응답 시간이 무엇인지 명시할 수 있다면, 제안된 시스템이 해당 사양을 충족하는지 테스트하는 데 주입기 구성을 사용할 수 있다.
## 질문
성능 사양은 최소한 다음 질문을 해야 한다. * 자세히, 성능 테스트 범위는 무엇인가? 어떤 서브 시스템, 인터페이스, 구성 요소 등이 이 테스트의 범위 내외에 있는가? * 관련된 사용자 인터페이스(UI)에 대해 각각 몇 명의 동시 사용자가 예상되는가(최대 대 명목 지정)? * 대상 시스템(하드웨어)은 어떤 모습인가(모든 서버 및 네트워크 장치 구성 지정)? * 각 시스템 구성 요소의 응용 프로그램 작업 부하 혼합은 무엇인가? (예: 20% 로그인, 40% 검색, 30% 항목 선택, 10% 결제). * 시스템 작업 부하 혼합은 무엇인가? [단일 성능 테스트에서 여러 작업 부하를 시뮬레이션할 수 있다] (예: 30% 작업 부하 A, 20% 작업 부하 B, 50% 작업 부하 C). * 모든 백엔드 배치 프로세스에 대한 시간 요구 사항은 무엇인가(최대 대 명목 지정)?
# 전제 조건
가능한 한 생산 환경과 유사해야 하는 안정적인 시스템 빌드. 일관된 결과를 보장하기 위해 성능 테스트 환경은 UAT (User Acceptance Testing) 또는 개발과 같은 다른 환경과 격리되어야 한다. 가장 좋은 방법은 가능한 한 생산 환경과 유사한 별도의 성능 테스트 환경을 갖는 것이 항상 권장된다.
## 테스트 조건
성능 테스트에서는 테스트 조건이 예상되는 실제 사용과 유사해야 하는 것이 종종 중요한다. 그러나 실제로는 이를 마련하기 어렵고 완전히 가능하지 않다. 생산 시스템은 예측할 수 없는 작업 부하에 노출되기 때문이다. 테스트 작업 부하는 가능한 한 생산 환경에서 발생하는 상황을 모방할 수 있지만, 가장 단순한 시스템에서만 이 작업 부하 변동성을 정확하게 복제할 수 있다. 느슨하게 결합된 아키텍처 구현(예: SOA)은 성능 테스트에 추가적인 복잡성을 야기했다. 생산과 유사한 상태를 진정으로 복제하려면 공통 인프라 또는 플랫폼을 공유하는 엔터프라이즈 서비스 또는 자산은 모든 소비자가 생산과 유사한 트랜잭션 볼륨 및 공유 인프라 또는 플랫폼에 부하를 생성하는 조정된 성능 테스트를 요구한다. 이 활동은 돈과 시간 면에서 매우 복잡하고 비용이 많이 들기 때문에 일부 조직에서는 이제 성능 테스트 환경(PTE)에서 생산과 유사한 조건(일명 "노이즈")을 모니터링하고 시뮬레이션하는 도구를 사용하여 용량 및 리소스 요구 사항을 이해하고 품질 속성을 확인/검증한다.
## 타이밍
새로운 시스템의 비용 성능에 있어 성능 테스트 노력이 개발 프로젝트의 시작부터 배포까지 확장되는 것이 중요하다. 성능 결함이 늦게 감지될수록 개선 비용이 더 높아진다. 이는 기능 테스트의 경우에도 마찬가지이지만, 범위의 엔드-투-엔드 특성 때문에 성능 테스트에서는 더욱 그렇다. 성능 테스트 팀이 가능한 한 빨리 참여하는 것이 중요하다. 테스트 환경 및 기타 주요 성능 필수 요소를 획득하고 준비하는 데 시간이 많이 걸리기 때문이다.
# 도구
성능 테스트는 주로 두 가지 주요 범주로 나뉜다:
## 성능 스크립팅
성능 테스트의 이 부분은 주로 주요 식별된 비즈니스 프로세스의 작업 흐름을 생성/스크립팅하는 것과 관련이 있다. 이는 다양한 도구를 사용하여 수행할 수 있다. 위 목록에 언급된 각 도구(포괄적이거나 완전하지 않음)는 스크립팅 언어(C, Java, JS) 또는 일부 형태의 시각적 표현(드래그 앤 드롭)을 사용하여 최종 사용자 작업 흐름을 생성하고 시뮬레이션한다. 대부분의 도구는 "기록 및 재생"이라는 기능을 허용하며, 성능 테스터가 테스트 도구를 실행하고 브라우저 또는 두꺼운 클라이언트에 연결하여 클라이언트와 서버 간에 발생하는 모든 네트워크 트랜잭션을 캡처한다. 이렇게 함으로써 다양한 비즈니스 시나리오를 에뮬레이션하기 위해 향상/수정될 수 있는 스크립트가 개발된다.
## 성능 모니터링
이것은 성능 테스트의 다른 측면을 형성한다. 성능 모니터링을 통해 테스트 중인 응용 프로그램의 동작 및 응답 특성이 관찰된다. 아래 매개변수는 일반적으로 성능 테스트 실행 중에 모니터링된다. 서버 하드웨어 매개변수 * CPU 사용률 * 메모리 사용률 * 디스크 사용률 * 네트워크 사용률 첫 번째 단계로, 이 네 가지 매개변수에 의해 생성된 패턴은 병목 현상이 어디에 있는지에 대한 좋은 지표를 제공한다. 문제의 정확한 근본 원인을 파악하기 위해 소프트웨어 엔지니어는 프로파일러와 같은 도구를 사용하여 장치 또는 소프트웨어의 어떤 부분이 성능 저하에 가장 큰 영향을 미치는지 측정하거나, 허용 가능한 응답 시간을 유지하기 위한 처리량 수준(및 임계값)을 설정한다.
# 기술
성능 테스트 기술은 하나 이상의 PC 또는 유닉스 서버를 주입기로 사용하여, 각각 여러 사용자의 존재를 에뮬레이트하고 각각 자동화된 상호작용 시퀀스(스크립트로 기록되거나 다른 유형의 사용자 상호작용을 에뮬레이트하는 일련의 스크립트로 기록됨)를 실행하여 성능을 테스트할 호스트와 상호작용한다. 일반적으로 별도의 PC가 테스트 지휘자 역할을 하여 각 주입기로부터 메트릭을 조율하고 수집하며 보고 목적으로 성능 데이터를 수집한다. 일반적인 시퀀스는 부하를 증가시키는 것이다. 즉, 소수의 가상 사용자로 시작하여 시간이 지남에 따라 미리 정해진 최대로 사용자 수를 늘리는 것이다. 테스트 결과는 사용자 수 대 응답 시간으로 주어지는 부하에 따라 성능이 어떻게 달라지는지 보여준다. 이러한 테스트를 수행하기 위한 다양한 도구가 있다. 이 범주의 도구는 일반적으로 시스템에 대해 실제 사용자를 에뮬레이트하는 일련의 테스트를 실행한다. 때로는 결과가 이상한 점을 드러낼 수 있다. 예를 들어, 평균 응답 시간은 허용될 수 있지만, 몇 가지 주요 트랜잭션의 특이값이 완료하는 데 훨씬 더 오래 걸리는 경우가 있다. 이는 비효율적인 데이터베이스 쿼리, 그림 등으로 인해 발생할 수 있다. 성능 테스트는 스트레스 테스트와 결합하여 허용 가능한 부하가 초과될 때 어떤 일이 발생하는지 확인할 수 있다. 시스템이 충돌하는가? 큰 부하가 줄어들면 복구하는 데 얼마나 걸리는가? 실패가 부수적인 피해를 초래하는가? 분석 성능 모델링은 스프레드시트에서 시스템의 동작을 모델링하는 방법이다. 모델은 트랜잭션 리소스 요구(CPU, 디스크 I/O, LAN, WAN) 측정값에 트랜잭션 혼합(시간당 비즈니스 트랜잭션)으로 가중치를 부여하여 공급된다. 가중 트랜잭션 리소스 요구는 시간당 리소스 요구를 얻기 위해 합산되고 시간당 리소스 용량으로 나누어 리소스 부하를 얻는다. 응답 시간 공식(R=S/(1-U), R=응답 시간, S=서비스 시간, U=부하)을 사용하여 응답 시간을 계산하고 성능 테스트 결과와 함께 보정할 수 있다. 분석 성능 모델링은 실제 또는 예상 비즈니스 사용을 기반으로 설계 옵션 및 시스템 크기 조정을 평가할 수 있도록 한다. 따라서 성능 테스트보다 훨씬 빠르고 저렴하지만 하드웨어 플랫폼에 대한 철저한 이해가 필요하다.
# 수행할 작업
이러한 테스트를 수행하기 위한 작업은 다음과 같다. * 사내 전문 지식(또는 부족)에 따라 테스트를 수행하기 위해 내부 또는 외부 리소스를 사용할지 결정한다. * 사용자와/또는 비즈니스 분석가로부터 성능 요구사항(사양)을 수집하거나 이끌어낸다. * 요구사항, 리소스, 타임라인 및 이정표를 포함한 상위 수준의 계획 (또는 프로젝트 헌장)을 개발한다. * 상세한 성능 테스트 계획 (상세 시나리오 및 테스트 케이스, 작업 부하, 환경 정보 등 포함)을 개발한다. * 테스트 도구를 선택한다. * 필요한 테스트 데이터를 지정하고 노력(종종 간과되지만 유효한 성능 테스트를 수행하는 데 필수적)을 시작한다. * 선택한 테스트 도구 및 전략을 사용하여 테스트 중인 각 응용 프로그램/구성 요소에 대한 개념 증명 스크립트를 개발한다. * 모든 종속성 및 관련 타임라인을 포함한 상세 성능 테스트 프로젝트 계획을 개발한다. * 주입기/컨트롤러를 설치 및 구성한다. * 테스트 환경을 구성한다 (이상적으로는 생산 플랫폼과 동일한 하드웨어), 라우터 구성, 조용한 네트워크 (다른 사용자로 인해 결과가 방해받지 않도록), 서버 계측 배포, 개발된 데이터베이스 테스트 세트 등. * 테스트를 시범 실행한다 – 미리 정의된 사용자로 부하 테스트를 실제로 실행하기 전에 스크립트의 정확성을 확인하기 위해 시범 실행을 수행한다. * 테스트를 실행한다 – 아마도 반복적으로(반복적으로) 예상치 못한 요인이 결과에 영향을 미칠 수 있는지 확인하기 위해. * 결과를 분석한다 – 통과/실패 또는 중요 경로 조사 및 시정 조치 권고.
# 방법론

## 웹 애플리케이션 성능 테스트
마이크로소프트 개발자 네트워크에 따르면 성능 테스트 방법론은 다음 활동으로 구성된다. # **테스트 환경을 식별한다.** 물리적 테스트 환경과 프로덕션 환경은 물론 테스트 팀이 사용할 수 있는 도구와 리소스를 식별한다. 물리적 환경에는 하드웨어, 소프트웨어 및 네트워크 구성이 포함된다. 초기에 전체 테스트 환경을 철저히 이해하면 보다 효율적인 테스트 설계 및 계획이 가능하며 프로젝트 초기에 테스트 과제를 식별하는 데 도움이 된다. 어떤 상황에서는 이 프로세스를 프로젝트의 수명 주기 전반에 걸쳐 주기적으로 다시 검토해야 할 수도 있다. # **성능 수용 기준을 식별한다.** 응답 시간, 처리량, 리소스 사용 목표 및 제약 조건을 식별한다. 일반적으로 응답 시간은 사용자 관심사, 처리량은 비즈니스 관심사, 리소스 사용은 시스템 관심사이다. 또한 이러한 목표 및 제약 조건으로 포착되지 않을 수 있는 프로젝트 성공 기준을 식별한다. 예를 들어, 성능 테스트를 사용하여 어떤 구성 설정 조합이 가장 바람직한 성능 특성을 가져올지 평가한다. # **테스트를 계획하고 설계한다.** 주요 시나리오를 식별하고, 대표 사용자 간의 가변성을 결정하고 해당 가변성을 시뮬레이션하는 방법, 테스트 데이터를 정의하고 수집할 메트릭을 설정한다. 이 정보를 구현, 실행 및 분석할 시스템 사용의 하나 이상의 모델로 통합한다. # **테스트 환경을 구성한다.** 기능 및 구성 요소가 테스트에 사용할 수 있게 됨에 따라 각 전략을 실행하는 데 필요한 테스트 환경, 도구 및 리소스를 준비한다. 필요한 경우 리소스 모니터링을 위해 테스트 환경이 계측되었는지 확인한다. # **테스트 설계를 구현한다.** 테스트 설계에 따라 성능 테스트를 개발한다. # **테스트를 실행한다.** 테스트를 실행하고 모니터링한다. 테스트, 테스트 데이터 및 결과 수집을 검증한다. 테스트 및 테스트 환경을 모니터링하면서 분석을 위해 검증된 테스트를 실행한다. # **결과 분석, 튜닝 및 재테스트한다.** 결과 데이터를 분석, 통합 및 공유한다. 튜닝 변경을 하고 재테스트한다. 두 테스트의 결과를 비교한다. 개선될 때마다 이전 개선보다 더 작은 개선이 이루어진다. 언제 멈춰야 하는가? CPU 병목 현상에 도달하면 코드를 개선하거나 CPU를 추가하는 두 가지 선택지가 있다.