반응형

출처: The Art of Software Testing, G. J. Myers, 1979, 페이지 122~129

 


 

방금 발견한 에러가 프로그램에 마지막 남은 에러인지 알 수 있는 방법이 없기 때문에 프로그램을 테스트 할 때 가장 답하기 어려운 문제 중 하나가 언제 중단해야 하는지를 결정하는 일이다. 사실 작은 프로그램을 제외하고 프로그램에서 모든 에러가 발견될 것이라고 기대하는 것은 합리적이지 않다. 이런 딜레마를 감안할 때 그리고 경제적 이유로 언젠가는 반드시 테스팅을 중단해야 한다는 사실을 감안할 때, 우리가 이 문제에 순전히 임의의 방식으로 답해야 할지 아니면 어떤 유용한 중단 기준이 존재하는지 의문을 가지게 된다.

 

현업에서 일반적으로 사용하는 완료 기준은 의미가 없으며 비생산적(counterproductive)인데, 가장 흔한 두 가지 기준으로 아래를 들 수 있다.

1. 계획한 테스트 일정이 만료되면 중단한다.

2. 모든 테스트케이스가 에러 발견 없이 실행되면 중단한다(, 테스트케이스가 에러 발견이라는 목표 달성에 실패한 경우).

 

첫 번째 기준은 아무것도 하지 않아도 만족할 수 있기 때문에 쓸모가 없다(, 테스팅 품질을 측정하는 기준이 되지 못한다). 두 번째 기준도 테스트케이스의 품질과 무관하기 때문에 똑같이 쓸모가 없다. 더욱이 이 기준이 무의식적으로 에러를 감지할 가능성이 낮은 테스트케이스를 작성하도록 장려하기 때문에 비생산적이까지 하다. 인간은 매우 목표 지향적이기 때문에 자신의 테스트케이스가 성공적이지 않을 때(버그를 찾지 못했을 때) 작업을 완수했다는 말을 들으면 무의식적으로 이런 목표를 향하는 테스트케이스를 작성하고 결함 발견 가능성이 높은 파괴적인 테스트케이스는 회피하게 된다.

 

 

아래 세 가지 범주의 좀 더 유용한 중단 기준도 존재한다.

 

1) 첫 번째 범주

특정 테스트케이스 설계 방법론(test-case-design methodologies) 사용에 기반하여 완료 기준을 정하는 것이다. 예를 들어, 모듈 테스팅의 완료를 다음 기준에 따라 결정할 수 있다.

테스트케이스는 (1) 다중조건 커버리지 기준(multicondition-coveage criterion) (2) 모듈 인터페이스 사양의 경계 값 분석(boundary-value analysis)을 충족하도록 도출하고, 도출된 모든 테스트케이스가 결국 실패(, 에러 발견 없이 실행됨)해야 한다.

 

또 다른 예로 다음 조건을 충족하면 기능 테스트를 완료하는 것으로 정의 할 수 있다.

테스트케이스는 (1) 원인-효과 그래프(cause-effect graphing), (2) 경계 값 분석(boundary-value analysis) (3) 에러 추측(error guessing)을 기반으로 도출하며, 도출된 모든 테스트케이스가 최종적으로 실패(, 에러 발견 없이 실행됨)해야 한다.

 

이러한 유형의 완료 기준이 앞서 언급한 두 가지 기준보다 우수하지만 세 가지 문제점이 있다. 첫째, 시스템 테스트 단계와 같이 특정 설계 방법론을 사용할 수 없는 테스트 단계에서는 도움이 되지 않는다. 둘째, 테스터가 특정 방법론(, 경계 값 분석)을 적절하고 엄격하게 적용했음을 보장할 방법이 없기 때문에 주관적인 측정이다. 셋째, 사람에게 목표(goal)를 부여하고 이를 달성하는 가장 적절한 방법을 선택하도록 하는 것이 아니라 그 반대이다. 즉 테스트케이스 설계 방법론에 따르지만 목표는 주어지지 않는다. 이러한 유형의 기준이 일부 테스트 단계에서 때때로 유용하지만, 과거에 테스트케이스 설계 방법론을 성공적으로 사용한 테스터의 능력이 입증된 경우에만 적용해야 한다.

 

2) 두 번째 범주

두 번째 범주의 기준은 완료 요구사항(completion requirements)을 긍정적 용어로 기술한 것이다. 테스팅의 목표가 에러를 찾는 것이므로, 완료 기준을 미리 정의된 에러 수를 발견하는 것으로 정하는 것이다. 예를 들어, 특정 모듈의 모듈 테스트 완료 기준을 아래와 같이 설정한다.

3개의 에러를 발견할 때까지는 모듈 테스트를 완료할 수 없다.

 

시스템 테스트 완료 기준의 경우 아래와 같이 정의 할 수 있다.

70개의 에러를 발견 및 수정하는 것과 3개월의 테스팅 시간을 가지는 것, 이 두 가지 모두 충족해야 한다(둘 중 어느 것이 나중에 충족되든 순서는 상관 없음).

 

이러한 유형의 기준은 테스트의 정의를 강화하지만 두 가지 문제점이 있다(둘 다 극복 가능한 문제임). 첫 번째 문제는 발견할 에러 수를 어떻게 알아낼지 결정하는 것인데, 이 숫자를 얻으려면 다음을 알아야 한다.  

 

1. 프로그램의 총 에러 수 추정치

2. 이러한 에러 중 몇 퍼센트를 테스트를 통해 찾을 수 있는지 추정치

3. 에러 중 몇 퍼센트가 특정 설계 프로세스에서 발생했는지 추정치와 어떤 테스팅 단계에서 이러한 에러가 발견될 가능성이 있는지 추정치

 

총 에러 수에 대한 대략적인 추정치는 여러 방식으로 확보할 수 있다. 한 가지 방법은 이전 프로그램에 대한 경험을 통해 얻는 것이다. 또한 다양한 예측 모델(predictive models)도 존재한다. 이 추정치를 얻는 또 다른 방법은 산업 전반의 평균치를 사용하는 것이다. 예를 들어, 코딩이 완료되는 시점(코드 워크쓰루 또는 코드 인스펙션이 수행되기 전)에 일반적인 프로그램에 존재하는 에러의 수가 100개의 프로그램 문장(statements) 당 대략 4~8개 이다.

 

두 번째 추정(테스팅을 통해 찾을 가능성이 있는 에러 비율)은 프로그램의 특질과 미발견 에러의 영향력을 고려하여 다소 임의적인 추측이 필요하다.

 

세 번째 추정은 에러가 어떻게그리고 언제만들어지는가에 대한 정보가 현재 부족하다는 점을 감안할 때 가장 어려운 작업이다. 현존하는 데이터에 따르면 대규모 프로그램에서 에러의 약 40%가 코딩/논리-설계 실수이며 나머지는 더 이른 설계 프로세스에서 발생한다고 한다.

 

실례(EXAMPLE)

우리가 이러한 완료 기준을 사용하려면 자신의 프로그램에 알맞은 추정치를 개발해야 하지만, 여기에 간단한 예를 들어 보겠다. 10,000개 문장(statements)으로 된 프로그램의 테스트를 시작하려 한다고 가정하고, 코드 인스펙션을 수행 한 후 남아 있는 에러 수가 100개 문장 당 5개 라고 추정한다. 우리 목표는 코딩/로직-설계 에러의 98%와 설계 에러의 95%를 발견하는 것이다. 총 에러 수가 500개로 추정되고, 이 중 200개는 코딩/논리-설계 에러이고 300개는 설계 결함이라고 가정한다. 따라서 목표는 196개의 코딩/논리-설계 에러와 285개의 설계 에러를 찾는 것이다. 언제 에러가 발견될지에 대한 추정이 표 6.1에 나와 있다.

 

6.1 언제 에러가 발견 될 수 있는지 대한 가설의 추정치

  코딩/논리-설계 에러 설계 에러
모듈 테스트 65 % 0 %
기능 테스트 30 % 60 %
시스템 테스트 3 % 35 %
합계 98 % 95 %

 

기능 테스팅에 4개월, 시스템 테스팅에 3개월을 일정으로 잡았다면 완료 기준이 다음과 같이 설정 될 수 있다.

1. 모듈 테스팅은 130개의 에러를 발견 및 수정하면 완료한다(추정된 200개의 코딩/논리-설계 에러의 65%).

2. 기능 테스팅은 240개의 에러(200개 중 30% + 300개 중 60%)를 발견 및 수정하였을 때, 또는 4개월의 기능 테스트가 만료되었을 때, 이 둘 중 뒤에 발생하는 것의 시점에 완료한다. (두 번째 절이 붙은 이유는 우리가 240개의 에러를 빠르게 찾은 경우 총 에러 수를 너무 적게 추산했기 때문일 수 있고, 따라서 기능 테스트를 조기 중단해서는 안 된다.)

3. 시스템 테스팅은 111개의 에러를 발견 및 수정하였을 때, 또는 3개월의 시스템 테스팅 기간이 만료되었을 때, 이 둘 중 뒤에 발생하는 것의 시점에 완료한다.

 

이러한 유형의 기준에 있어서 또 다른 명백한 문제점은 에러 수를 과다 추정하는 경우이다. 위의 예에서 기능 테스트가 시작되는 시점에 실제 남은 에러 수가 240개 미만이라면 어떻게 될 것인가? 정해진 기준에 따르면 우리가 기능 테스트 단계를 절대 완료 할 수 없다(사실 프로그램이 너무 잘 작성되어서 에러가 충분히 많지 않은 것은 환영할 일이기 때문에 이걸 "문제"라고 부를 수는 없다). 만약 이런 일이 발생하면 약간의 상식으로 해결 가능하다. 4개월 동안 240개의 에러를 찾을 수 없는 경우 프로젝트 관리자는 테스트케이스를 분석할 외부인을 고용하여 다음을 판단하도록 한다.

(1) 테스트케이스가 부적절하여 에러를 찾지 못한다.

(2) 테스트케이스는 우수하지만 발견할 에러 자체가 부족하기 때문에 에러를 찾지 못한다.

 

 

3) 세 번째 범주

세 번째 유형은 표면적으로는 쉬운 기준이지만 많은 판단과 직관을 필요로 한다. 이 기준을 사용하기 위해서는 테스트 단계의 단위 시간당 발견 에러 수를 그래프에 표시해야 한다. 그래프 곡선의 모양을 검토하여 테스트 단계를 계속할지 아니면 종료하고 다음 테스트 단계를 시작할지 결정한다.

 

예를 들어, 프로그램이 기능 테스트 중이고 매 주 발견 된 에러 수를 그래프에 플로팅(plotting)한다고 가정하자. 7주차의 곡선이 그림 6.5의 왼쪽과 같은 경우, 발견 할 에러 수에 대한 우리 기준에 도달 했더라도 기능 테스트를 중단하는 것은 경솔하다. 7주차에도 여전히 기세가 올라 있으므로(많은 에러를 찾는 중) 가장 현명한 결정은 기능 테스트를 계속하고, 필요한 경우 추가 테스트케이스를 설계하는 것이다(우리의 목표가 에러를 찾는 것임을 잊지 말자).

 

반면 곡선이 그림 6.5의 오른쪽과 같은 경우 에러 발견 효율성이 크게 떨어진 것을 알 수 있다. 이는 아마도 우리가 기능 테스트라는 뼈를 깨끗하게 발라먹었으며, 가장 좋은 수는 기능 테스트를 종료하고 새로운 유형의 테스트(, 시스템 테스트)를 시작하는 것임을 암시한다(물론 에러 발견 효율성 저하가 컴퓨터 시간 부족이나 사용 가능한 테스트케이스 고갈로 인한 것인지 같은 다른 요인도 고려해야 한다).

그림 6.5 단위 시간 당 발견 에러에 따른 완료 시점 추정

 

그림 6.6은 테스터가 발견 된 에러 수를 제대로 표시하지 않았을 때 어떤 일이 발생하는지 보여준다. 이 그래프는 아주 대규모 소프트웨어 시스템의 세 가지 테스팅 단계를 나타내며, 해당 프로젝트의 사후 연구(post-mortem study)의 일환으로 작성되었다. 분명한 결론은 이 프로젝트가 기간 6(Period 6) 이후에 다른 테스팅 단계로 전환해서는 안되었다는 점이다. 기간 6 동안 에러 발견율이 좋았는데(테스터에게는 발견율이 더 높을수록 더 좋다), 이 시점에 두 번째 단계로 전환한 것이 에러 발견율을 크게 떨어뜨리는 결과를 낳았다.

그림 6.6 대규모 프로젝트의 테스팅 프로세스에 대한 사후 연구

 

 

결론

가장 좋은 완료 기준은 위에서 설명한 세 가지 유형의 조합 일 것이다. 모듈 테스트의 경우, 특히 대부분의 프로젝트가 이 단계 동안은 발견된 에러를 공식적으로 추적하지 않기 때문에, 아마도 첫 번째 범주가 최상의 완료 기준이 될 것이다. , 특정 테스트케이스 설계 방법론을 사용하도록 요청해야 한다. 기능 테스트 및 시스템 테스트 단계의 경우 완료 규칙은, 에러 대비 시간 그래프의 분석에서 테스트가 더 이상 생산적이지 않다는 전제 하에, 미리 정의된 에러 수가 발견되었을 때 또는 예정된 시간이 경과했을 때, 둘 중 더 늦게 이루어지는 것에 맞추어 중단한다.

 

 

반응형

+ Recent posts