테스트 디자인에 사용되는 정보는 디자인 모델, 클래스류 인터페이스, 상태 차트 및 코드 자체와 같은 여러 위치에서 수집됩니다. 일정 시점에 이 소스 문서 정보는 실행 가능 테스트로 변환됩니다.
-
테스트 시 소프트웨어에 제공되는 특정 입력
-
특정 하드웨어 및 소프트웨어 형상
-
알려진 상태로 초기화됨
-
예상되는 특정 결과
소스 문서 정보에서 실행 가능 테스트로 직접 이동할 수 있지만 중간 단계를 추가하는 것이 유용합니다. 이 단계에서 테스트 아이디어는 실행 가능 테스트 작성에 사용되는 테스트 아이디어 목록에 기록됩니다.
테스트 아이디어(테스트 요구사항이라고도 함)는 수행할 수 있는 테스트에 대한 간략한 설명입니다. 단순 예제로서 제곱근을 계산하는 함수를 고려해 보면 다음과 같은 테스트
아이디어가 떠오릅니다.
-
거의 0 미만인 숫자를 입력으로 제공
-
0을 입력으로 제공
-
4 또는 16과 같은 완전제곱 숫자 테스트(결과는 정확히 2 또는 4입니까?)
이러한 각각의 아이디어는 입력 및 예상 결과의 정확한 설명을 사용하여 즉시 실행 가능 테스트로 변환될 수 있습니다.
이 덜 특정한 중간 양식에는 두 가지 장점이 있습니다.
-
테스트 아이디어가 전체 테스트보다 검토 가능하고 이해 가능합니다. 테스트 아이디어의 배경 이유를 이해하기가 더 쉽습니다.
-
테스트 아이디어는 보다 강력한 테스트를 지원합니다(나중에 설명되는 목록을 사용하는 테스트 디자인 참조)
제곱근 예제는 입력을 모두 설명하지만 테스트 아이디어는 실행 가능 테스트의 모든 요소를 설명할 수 있습니다. 예를 들어 "LaserJet IIIp로 인쇄"는 테스트에 사용되는 테스트 환경 측면을 설명하고 "가득찬 데이터베이스로 테스트"도 마찬가지지만 후자 테스트 아이디어는 자체만으로는 매우
불완전합니다. 프린터로 무엇을 인쇄합니까? 가득찬 데이터베이스로 무엇을 수행합니까? 그러나 이들은 중요한 아이디어가 무시되지 않도록 합니다. 자세한 내용은 테스트 디자인의 뒷부분에서
설명됩니다.
테스트 아이디어는 종종 결함 모델을 기반으로 합니다. 결함 모델은 소프트웨어의 그럴듯한 결함 및 해당 결함을 가장 잘 발견할 수 있는 방식의 개념입니다. 예를
들어 경계를 고려해 보십시오. 제곱근 함수가 다음과 같이 구현될 수 있음을 가정하는 것이 안전합니다.
double sqrt(double x) {
if (x < 0)
// signal error
...
<를 <=로 잘못 입력할 수도 있습니다. 종종 이런 실수를 하므로 확인이 필요합니다. 잘못된 표현식 (x<=0) 및 올바른 표현식 (x<0)은
동일한 if 명령문의 분기를 사용하기 때문에 값이 2인 X로 결함을 발견할 수 없습니다. 마찬가지로 X에 값 -5를 제공해도 결함을 찾을 수 없습니다.
결함을 찾으려면 X에 값 0을 제공해야 하며, 이로써 두 번째 테스트 아이디어가 입증됩니다.
이 경우 결함 모델은 명시적입니다. 다른 경우에는 내재적입니다. 예를 들어 프로그램이 링크된 구조를 조작할 때마다 순환 구조에 대해 프로그램을 테스트하는 것이 좋습니다. 여러 결함으로 인해 순환 구조가 잘못 처리될
수도 있습니다. 테스트 목적으로 결함 모델을 열거할 필요는 없습니다. 테스트를 실행해야 할만한 일부 결함의 발생 가능성을 인식하는 것으로 충분합니다.
다음 링크는 서로 다른 유형의 결함 모델에서 테스트 아이디어를 가져오는 방법에 대한 정보를 제공합니다. 첫 번째 링크는 명시적 결함 모델이고 마지막은 내재적 결함 모델을 사용합니다.
이러한 결함 모델은 여러 다른 중간 산출물에 적용될 수 있습니다. 예를 들어 첫 번째 결함 모델은 부울 표현식으로 수행할 작업을 설명합니다. 해당 표현식은 코드, 보호 조건, 상태 차트와 시퀀스 다이어그램 및
메소드 동작의 원시 언어 설명(게시된 API에서 찾을 수 있음)에서 찾을 수 있습니다.
때때로 특정 중간 산출물에 대한 가이드라인이 있는 것도 도움이 됩니다. 가이드라인: 상태 차트 및 플로우 다이어그램에 대한 테스트 아이디어를 참조하십시오.
특정 테스트 아이디어 목록은 여러 결함 모델의 테스트 아이디어를 포함할 수 있고 해당 결함 모델은 둘 이상의 중간 산출물에서 파생될 수 있습니다.
순차 콜렉션에서 문자열을 검색하는 메소드에 대한 테스트를 디자인하고 있다고 가정해 보십시오. 메소드는 검색 시 대소문자를 구분하거나 구분하지 않을 수 있으며 발견된 첫 번째 일치의 색인을 리턴하거나 일치가 없는
경우 -1을 리턴합니다.
int Collection.find(String string,
Boolean ignoreCase);
다음은 이 메소드에 대한 일부 테스트 아이디어입니다.
-
첫 번째 위치에서 찾은 일치
-
마지막 위치에서 찾은 일치
-
일치 없음
-
콜렉션에서 찾은 둘 이상의 일치
-
대소문자 구분 안함. 일치를 찾았으나 대소문자 구분 시 일치하지 않음
-
대소문자 구분. 정확한 일치를 찾음
-
대소문자 구분. 대소문자 구분 안하는 경우 찾을 수 있는 문자열은 건너뜀
이러한 테스트 아이디어마다 하나씩 일곱 개의 테스트를 구현하는 것은 단순합니다. 그러나 여러 테스트 아이디어를 단일 테스트로 결합할 수 있습니다. 예를 들어 다음 테스트는 아이디어 2, 6, 7을
충족합니다.
설정: collection initialized to ["dawn", "Dawn"]
호출: collection.find("Dawn", false)
예상 결과: 리턴값은 1("dawn"을 건너뛰지 않은 경우에는 0)
테스트 아이디어를 특정하지 않게 만들면 보다 쉽게 결합할 수 있습니다.
세 개의 테스트로 모든 테스트 아이디어를 충족할 수 있습니다. 일곱 개의 테스트 아이디어를 충족하는 세 개의 테스트가 별도의 일곱 개 테스트보다 좋은 이유는 무엇입니까?
-
많은 수의 단순 테스트를 작성할 때 테스트 N을 복사하여 새 테스트 아이디어를 충족하도록 조정하는 방식으로 테스트 N+1을 작성하는 것이 공통적입니다. 특히 보다 복잡한 소프트웨어에서 결과적으로 테스트
N+1은 테스트 N과 거의 같은 방식으로 프로그램을 실행합니다. 코드를 통해 거의 정확하게 같은 경로를 사용합니다.
각각 여러 테스트 아이디어를 충족하는 이보다 수가 적은 테스트는 "복사 및 조정" 접근 방식을 허용하지 않습니다. 각 테스트는 마지막 테스트와 약간 다르고 다른 방식으로 코드를 실행하고 다른 경로를
사용합니다.
그런데도 좋은 이유는 무엇입니까? 테스트 아이디어 목록이 완전하면, 즉 프로그램의 모든 결함에 대한 테스트 아이디어가 포함되어 있으면 테스트를 작성하는 방식은 문제가 되지 않습니다. 그러나 목록에는 항상
버그를 찾을 수 있는 일부 테스트 아이디어가 빠져 있습니다. 불필요할 수 있는 다양성을 추가하여 각 테스트가 마지막 테스트와 완전히 다른 것을 수행하게 하면 테스트 중 하나가 우연히 버그를 찾을 가능성이
증가합니다. 실제로 테스트가 더 작고 더 복잡할수록 테스트가 몰랐지만 필요한 테스트 아이디어를 충족할 가능성이 증가합니다.
-
때로는 보다 복잡한 테스트를 작성할 때 새 테스트 아이디어가 떠오릅니다. 단순 테스트는 수행하고 있는 작업이 마지막 테스트와 거의 같기 때문에 생각을 무디게 하므로 아이디어가 생각나는 경우가 더 적습니다.
그러나 복잡한 테스트를 작성하지 않는 여러 이유가 있습니다.
-
각 테스트가 하나의 테스트 아이디어를 충족하고 아이디어 2에 대한 테스트가 실패하면 프로그램이 마지막 위치의 일치를 처리하지 않았기 때문일 수 있음을 즉시 알게 됩니다. 테스트가 아이디어 2, 6, 7을
충족하면 실패 분리가 강화됩니다.
-
복잡한 테스트는 이해하고 유지보수하기가 더 어렵습니다. 테스트의 의도가 덜 명확합니다.
-
복잡한 테스트는 작성하기가 더 어렵습니다. 다섯 개의 테스트 아이디어를 충족하는 테스트를 구성하면 각각 하나의 테스트 아이디어를 충족하는 다섯 개의 테스트를 구성하는 것보다 시간이 더 걸립니다. 또한 네
개만 충족할 때 다섯 개 모두 충족한다고 생각하는 실수를 저지르기 더 쉽습니다.
실제로 복잡도 및 단순성 사이에서 적절히 밸런스를 조절해야 합니다. 예를 들어 소프트웨어에 대해 수행할 첫 번째 테스트(일반적으로 스모크(smoke) 테스트)는 단순하고 이해와 유지보수가 쉽고 대부분의 명확한 문제점을 발견하도록 작성되어야 합니다. 나중에 테스트는 보다
복잡해지지만 유지보수할 수 없을 정도로 복잡해지지는 않습니다.
테스트 세트를 완료한 후 개념: 개발자 테스트에 설명된 특성 테스트 디자인 실수를 테스트 세트에서 확인하는 것이 좋습니다.
테스트 아이디어 목록은 디자인 중간 산출물의 검토 및 검수에 유용합니다. 예를 들어 Department 및 Employee 클래스 간의 연관을 표시하는 디자인 모델의 이 파트를 고려하십시오.
그림 1: Department 및 Employee 클래스 간 연관
모델에서 테스트 아이디어를 작성하는 규칙은 부서에 많은 직원이 있는 경우를 고려하게 합니다. 디자인을 둘러보고 "이때 부서에 많은 직원이 있으면 어떻겠습니까?"라고 질문하면 디자인 또는 분석 오류를 발견할 수
있습니다. 예를 들어 부서 간에 한 번에 한 명의 직원만 이동할 수 있음을 알게 될 수 있습니다. 기업이 많은 직원을 이동해야 하는 재편성을 신속하게 수행하려는 경우 이 규칙이 문제가 될 수 있습니다.
해당 결함, 가능성이 간과된 경우를 제외의 결함이라고 합니다. 결함 자체와 같이 테스트 노력에서 이러한 결함을 발견하는 테스트를 생략했을 수 있습니다. 예를 들어 제외의 결함이 배치로 이스케이프되는
빈도를 표시하는 [GLA81], [OST84], [BAS87], [MAR00] 및 기타
연구를 참조하십시오.
디자인 활동의 테스트 역할은 개념: 테스트 우선
디자인에 추가로 설명됩니다.
추적성은 절충과 관련됩니다. 추적성 값이 추적성을 유지보수할 만큼 가치가 있습니까? 이 질문은 타스크: 평가 및 추적성 필요 정의 과정에서 고려되어야 합니다.
추적성이 가치가 있는 경우에는 일반적으로 테스트가 수행되도록 한 중간 산출물까지 다시 테스트를 추적합니다. 예를 들어 API 및 테스트 간 추적성이 있을 수 있습니다. API가 변경되면 변경할 테스트를 알고
있습니다. 코드(API를 구현하는 코드)가 변경되면 실행할 테스트를 알고 있습니다. 테스트가 혼동되면 테스트 대상인 API를 찾을 수 있습니다.
테스트 아이디어 목록은 다른 레벨의 추적성을 추가합니다. 테스트에서 테스트가 충족하는 테스트 아이디어까지 추적한 다음 테스트 아이디어에서 원래 중간 산출물까지 추적할 수 있습니다.
|