- 웹 서비스의 스트레스 테스트
- QC/품질관리
- 2005. 8. 30. 19:28
테스터를 위한 가이드라인 by Chris Wilkinson, 소프트웨어 엔지니어, IBM
웹 서비스는 분산 컴퓨팅의 심장이며, 그들 간 인터랙션은 테스트가 까다롭다. 스트레스 테스트는 코드 결함을 탐지하는 효율적인 방법이다. 단, 스트레스 시스템이 효과적으로 구현되어야 한다. 이 글을 통해 스트레스 시스템의 기본적인 필요조건을 알아본다.
테스트 방식
전통적인 테스트 방식에는 일정한 형식의 간단한 단위 테스트(Unit Testing)가 포함되어 있다. 이는 종종 개발자들이 수행한다. 이 테스트들은 소프트웨어 내부에 대한 지식을 기반으로 설계되었고 제품의 아주 작고 특정한 부분을 테스트할 목적으로 수행되었다. 이러한 종류의 테스트들은 다른 코드 컴포넌트와 관계가 조금 있거나 거의 없는 단순한 웹 서비스에 잘 맞는다.
기능 검증(Functional Verification)은 제품의 소스 코드에 대해 제한된 지식을 갖고 있는 디자이너가 제품 또는 서비스의 핵심 기능을 확인하도록 하는 테스트 과정이다. 이 테스트들은 핵심 기능들이 스팩에 순응하는지를 확인하도록 설계된다. 예를 들어, 나의 온라인 경매가 입력된 대로 정확한 비드(bid)를 디스플레이하는가? 보험 브로커 시스템이 가장 저렴한 가격을 찾아내는가? 만일 이러한 테스트가 실패하면 이 제품의 근본적인 문제는 발견되기 마련이다(그리고 보통 이러한 문제는 픽스가 단순하다). 이러한 테스트 역시 단순한 웹 서비스에 알맞고 서비스가 각각의 기능을 정확히 수행하는지 여부를 검사할 수 있다.
시스템 테스트(System Test)는 기능 검증(Functional Verification) 단계가 완료된 후 발생한다. 즉 핵심 기능이 확인된 후에 발생한다. 전체 시스템의 문제를 포괄적으로 테스트한다. 웹 서비스가 시스템의 일부로서 어떻게 작동하는지, 다른 것들과 어떻게 인터랙트 하는지를 검사한다. 시스템 테스트(System Test) 단계는 개발 과정 중 마무리 단계에 이르러 발생한다. 이를 수행하는데 할당된 시간은 적다. 빡빡한 배포 스케쥴과 개발 방향의 변경으로 인해 시스템 테스트 단계는 종종 간과되고, 드러나는 특정 버그는 너무나 빈번해서 탐지되지도 않는다. 버그가 발견되더라도 원인을 밝혀내고 픽스를 시도하기에는 늦는 경우가 종종 있다. 따라서 시스템 테스트 애플리케이션은 코드 오류를 가능한 효율적으로 찾아낼 수 있도록 설계되어야 한다. 시스템 테스트는 다음 세 가지 분야로 구성된다.
1. 퍼포먼스 : 해당 제품의 통계를 결정하는 과정. 예를 들어, 초당 메시지 수는? 서비스 동시 사용자들의 허용 수는?
2. 시나리오 : 고객이 요구하는 정확한 구성을 만들어내는 과정. 이 시나리오에서 발견된 문제들은 고객이 제품을 사용하기 전에 탐지될 수 있다.
3. 스트레스 (또는 워크로드 밸런싱) : 과중한 워크로드를 적용하여 소프트웨어를 최대로 작동시키도록 설계된 점으로 볼 때, 위 두 분야와는 다르다. 제품을 강도높게 사용하여 효과적으로 수행되기만 한다면 스트레스 테스팅은 위에 언급한 기술로 발견할 수 없는 모호한 많은 버그를 발견한다. (이 경우 픽스 또한 가장 어렵다).
위 세 개의 시스템 테스트 요소들 중 가장 효율적인 것은, 코드 오류 탐지 관점에서 볼 때, 스트레스 테스팅(stress testing)이다. 하지만 이 과정은 시스템 테스트 또는 기능 테스팅의 다른 요소들과 종종 혼동되고 이 과정에 포함된 방식도 정확하게 구현되지 않는다.
스트레스 버그
스트레스 테스트를 통해 발견할 수 있는 버그는 상당히 다양하다. 이들은 다른 테스트 방식으로는 발견하기 힘들다. 다음이 두 가지 유형이 있다:
1. 메모리 유출 : 가장 탐지하기 어려운 현상. 메모리 유출은 배포된 제품에서 발견될 때가 종종 있는데 이들을 감지할 테스트 케이스를 디자인하는 것이 매우 어렵기 때문이다. 간단한 기능 테스트를 통해 메모리 유출은 극히 드물게 발견되는데 테스트가 완료되기 전에는 제품을 충분히 사용할 수 없기 때문이다. 메모리 소비가 인식될 정도가 되게 하려면 수차례 작동을 반복해야 한다. 메모리 유출을 C/C++ 같은 언어들보다 자바 프로그램에 도입하는 것이 더 어렵지만, 프로그램이 객체에 대한 레퍼런스를 갖고있는 한 객체가 인스턴스화되고 할당받는 것은 여전히 가능하다.
2. 병행성과 동기화 : 스트레스 테스트는 병행성 문제를 찾아내는데 단연 돋보인다. 다양한 코드 경로들과 하나의 테스트 수명기간 동안 실행할 타이밍 조건 때문이다. 교착상태(Deadlocks), 쓰레드 유출, 일반적인 동기화 문제들은 스트레스 테스트 단계에서만 종종 탐지된다. 단위 테스트를 실행하여 이러한 유형의 문제들을 찾는 것은 매우 어렵다. 개발자들은 그들의 코드가 다른 영역의 코드들과 어떻게 인터랙팅하는지를 항상 고려해야하는 것은 아니다.
기존 스트레스 툴
개발중인 제품을 스트레스 테스트 할 수 있는 툴들이 있다. 이러한 툴 대부분은 웹 서비스를 타겟으로 하는 툴이다. 하지만 이러한 툴 대부분은 단순한 HTML/SOAP 생성기로서 많은 클라이언트 연결을 시뮬레이팅하고 따라서 웹 서버에 높은 부하를 만들어낸다. 이러한 툴들은 기본적인 스트레싱에는 유용하지만 같은 기능적 태스크를 반복적으로 수행하는 기능 검증 (Functional Verification)단계의 확장에 불과하다. 시간과 리소스가 충분히 사용할 수 있다면 커스텀 구현의 스트레스 테스팅 시스템을 만듦으로서 보다 효과적인 테스팅을 할 수 있다. 스트레싱 시스템의 설계자는 테스트를 받고 있는 제품과 웹 서비스에 대한 지식을 갖고 있기 때문에 스트레스 시스템이 특정 부분의 코드를 목표로 정할 수 있다.
스트레스 애플리케이션 디자인
웹 서비스를 스트레싱할 테스트 시스템은 특별한 방식으로 코드를 실행하도록 설계되어야한다. 이러한 스타일은 기능 검증의 수준을 뛰어넘어 웹 서비스가 기대하는 일을 수행하는지 여부 뿐만 아니라 특정한 스트레스 조건이 적용될 때 지속적으로 실행 상태를 유지할 수 있는지를 검사한다. 스트레스 테스트가 웹 서비스에 적용해야하는 네 개의 기본적인 조건이 있다. 검증된 많은 스트레스 시스템들은 이 조건들을 적용하고 있다. 효과적인 스트레스 테스팅 시스템은 다음의 핵심 조건을 적용한다.
1. 반복 : 스트레스 조건을 이해할 수 있는 가장 확실하고 쉬운 방법은 아마도 '테스트 반복'일 것이다. 다시말하면, 테스트 반복은 특정 작동이나 기능을 계속하여 반복적으로 수행하는 것을 의미한다. 이를 테면 웹 서비스를 반복적으로 호출하는 것도 이에 속한다. 기능 검증(Functional Verification) 테스트는 작동이 실행되는지의 여부를 검사하도록 설계될 수 있다. 스트레스 테스트는 실행이 작동하는지와 테스트가 실행될 때 지속적으로 작동하는지를 검사한다. 제품이 실제 환경에서 사용되기에 적합한지의 여부를 결정하는 데에 반드시 필요하다. 일반적으로 사용자들은 제품을 반복적으로 사용하기 때문에 스트레스 테스팅은 사용자 보다 앞서 코드 결함을 찾아내야한다. 많은 단순한 스트레스 시스템들은 오직 이러한 조건을 구현하지만 기능 검증 테스트가 여러번 반복하도록 단순히 확장하는 것만으로는 효과적인 스트레스 테스트를 수행할 수 없다. 다음의 원리들을 조합하여 사용할 때 반복은 모호한 코드 결함을 발견할 수 있다.
2. 병행성 : 병행성은 여러 작동들을 동시에 수행하는 것이다. 다른 말로 표현하면 동시에 여러 테스트들을 수행하는 것, 예를 들어 같은 서버에서 동시에 많은 웹 서비스를 호출하는 것도 이에 포함된다. 이 원리가 모든 제품에 적용되는 것은 아니지만 대부분의 소프트웨어는 병행 작동이나 멀티 쓰레드 작동 요소를 갖고 있어서 코드에서 여러 인스턴스들을 실행시켜서 테스트 될 수 있다. 기능 테스트 또는 단위 테스트는 병행 디자인에 잘 결합되지 않는다. 스트레스 시스템은 기능 테스트보다 한 수 위여서 동시에 여러 개의 코드 경로를 실행할 수 있다. 이는 특정 제품에 의존한다. 예를 들어, 웹 서비스 스트레스 테스트가 한 번에 여러 개의 클라이언트를 시뮬레이트 해야한다고 가정해보자. 웹 서비스(또는 멀티 쓰레디드 코드)는 일반적으로 쓰레드 인스턴트 중 몇 개의 공유 데이터에 접근할 것이다. 프로그래밍의 가외 범위 때문에 더해지는 복잡함은 코드가 병행성 때문에 많은 오류를 갖고 있음을 의미한다. 병행성을 도입한다는 것은 한 쓰레드에 있는 코드가 다른 쓰레드의 코드로 인해 방해받는다는 것을 의미하기 때문에 결함이 발견되는 것이다. 반복의 원리를 결합하여 많은 코드 경로와 타이밍 조건을 포함시킬 수 있다.
3. 크기(Magnitude) : 제품에 적용되어야 하는 스트레스 시스템의 또 다른 조건은 하나의 작동에 적용되는 로드의 양을 고려해야한다. 스트레스 테스트는 작동을 반복적으로 수행할 수 있지만 그 작동은 제품 그 자체를 손상시킬 것이다. 예를 들어 클라이언트가 메시지를 입력할 수 있는 웹 서비스가 있다면 많은 메시지를 입력하는 클라이언트를 시뮬레이팅하여 하나의 작동에 높은 가용성을 줄 수 있다. 다시말해서 작동의 크기(Magnitude)를 높이는 것이다. 크기는 언제나 애플리케이션 스팩이지만 사용자가 측정 및 변경할 수 있는 제품에서 값을 확인할 수 있다. 예를 들어 데이터 사이즈, 지연 길이, 전송량, 인풋 속도, 인풋 종류 등이 그것이다. 하나의 강력한 작동이 코드 결함을 찾지 못할 수 있지만 다른 스트레스 원리들을 결합하여 문제를 찾을 수 있는 기회를 늘인다.
4. 임의 변동 : 마지막으로, 어떤 스트레스 시스템도 임의성의 요소 없이 완성될 수 없다. 이전의 스트레스 원리들을 도입한 수 많은 변수들을 임의적으로 사용한다면 테스트가 실행될 때마다 다양한 많은 코드 경로를 포함할 수 있다. 반복을 통해 반복들 간 시간, 재시작이나 서비스에 재연결하기 전의 반복의 수, 반복되는 웹 서비스의 순서들간 시간을 다르게 할 수 있다. 병행성의 경우 함께 수행되는 웹 서비스, 한번에 실행되는 웹 서비스의 수, 다른 서비스를 여러번 실행하는 경우 또는 같은 인스턴스를 많이 실행하는 경우를 다르게 할 수 있다. 크기는 아마도 변경이 가장 쉬울 것이다. 테스트가 반복될 때마다 애플리케이션에 보이는 변수들을 변경할 수 있다. 테스트가 완전히 임의적이라면 스트레스 오류를 지속적으로 다시 만들기는 어렵기 때문에 몇몇 시스템들은 constant random seed에 기반한 임의 변동을 사용한다.
일반적으로 스트레스 테스트는 위에 열거한 모든 것을 결합하게 될 것이다. 또한 허용된 시간이 끝날때 까지 실행할 것이다. 테스트에 허용된 실행 시간이 길 수록 더 많은 코드 경로가 포함되고 발견되는 결함 역시 많다. 오류가 일단 발견되면 진단 후 치료되어야 하는 것은 물론이다. 스트레스 테스트에서 코드 오류는 실행 후 며칠이 지나서 발견될 수 있기 때문에 시스템은 무엇인가 잘못 되었을 때 사용가능한 디버그 정보를 만들어야 한다.
'QC > 품질관리' 카테고리의 다른 글
조엘 테스트: 소프트웨어팀 평가 테스트 방법 (0) | 2005.10.31 |
---|---|
소프트웨어 기술성 평가 기준 해설서 (0) | 2005.10.31 |
웹오피스 3종 벤치마킹 (0) | 2005.10.28 |
응용 프로그램에 대해 Windows 2000 호환성 테스트 (0) | 2005.10.27 |
품질보증·품질관리 (0) | 2005.09.14 |
프로젝트 품질관리의 기본「품질 제어 vs 품질 보증」 (0) | 2005.09.14 |
글꼴 관련 정보 (0) | 2005.09.06 |
[자료] 테스터의 역할 및 SW테스트기법 (0) | 2005.08.30 |
[자료] mantis설치순서입니다 (0) | 2005.08.30 |
QC 관련 자료를 모아 두었습니다. (0) | 2005.08.30 |
Recent comment