제목: Reviewing 25 Years of Testing Technique Experiments
저자: NATALIA JURISTO, ANA M. MORENO, SIRA VEGAS, 스페인
문서유형: 학계 논문, 38페이지, 2004년
소프트웨어 개발의 한 부분인 테스팅 영역(더 구체적으로는 테스트케이스 선별 기준을 제공하는 테스팅 기법)에 대한 지식의 성숙도 수준을 그 실증적 연구 문헌 검토를 통해 분석한 논문이다. 이 논문에서 기존 테스팅 기법들을 분류한 부분만 발췌함
테스팅 기법들의 범주
무작위 테스팅 기법(Random testing techniques)
이 패밀리는 가장 오래되고 가장 직관적인 기법들로 구성된다. 이 패밀리에 속하는 기법들은 사전 설정된 어떤 지침(guidelines) 없이 테스트케이스를 무작위로 생성하는 것을 제안한다. 그렇지만 실제로 100% 순수한 무작위성(pure rendomness)을 보이는 기법은 거의 없으며 이 패밀리의 두 가지 변종이 가장 일반적으로 사용된다.
기능적 테스팅 기법(Functional testing techniques)
이 패밀리는 프로그램 사양(program specification)을 사용하여 테스트케이스를 생성하는 접근법을 제안한다. 테스트할 컴포넌트를 블랙박스로 간주하고 그 동작(behavior)은 입력 및 출력의 관찰을 통해 결정된다. 이 패밀리의 기법들은 가능한 시스템 입력 집합 중 비정상적인 시스템 동작을 유발하는 입력으로 구성된 서브집합에 주목하며, 테스트케이스를 생성하기 위한 핵심은 이런 서브집합에 속할 확률이 높은 시스템 입력을 찾는 것이다. 이를 위해 시스템 입력 집합을 동등 클래스(equivalence classes)라는 하위 집합으로 나누는 데, 동등 클래스에 속한 각 요소들의 동작이 유사하므로 이 클래스의 모든 요소가 비정상적 또는 정상적인 시스템 동작을 유발하는 입력이 된다. 이 패밀리를 구성하는 기법들은 동등 클래스를 얼마나 철저하게 커버하는지 그 엄격성(rigorousness) 측면에서 서로 다르다.
제어 흐름 테스팅 기법(Control flow testing techniques)
제어 흐름 테스팅 기법들은 소스 코드를 알아야 한다. 이 패밀리는 프로그램을 통과하는 일련의 경로를 선택하여 프로그램 제어 모델(control model)을 검사한다. 이 패밀리에 속하는 기법들은 코드를 얼마나 철저하게 커버하는지 그 엄격함 측면에서 차이가 있다.
데이터 흐름 테스팅 기법(Data flow testing techniques)
데이터 흐름 테스팅 기법들도 소스 코드에 대한 지식을 필요로 한다. 이 패밀리의 목표는 데이터 상태에 관련된 이벤트 시퀀스를 탐색하기 위한 프로그램 경로를 선택하는 것이다. 이 패밀리에 속하는 기법들은 코드 변수 상태를 커버하는 엄격함 정도에 따라 차이가 있다.
뮤테이션 테스팅 기법(Mutation testing techniques)
뮤테이션 테스팅 기법은 뮤테이션 연산자(프로그래밍 언어에 따라 다름)를 통해 전형적인 프로그래밍 에러를 모델링 하는 것을 기반으로 한다. 각 뮤테이션 연산자가 프로그램에 적용되어 일련의 뮤턴트(뮤테이션 연산자에 의해 생성된 변이 문장 하나를 제외하고는 원래 프로그램과 정확히 동일한 프로그램)를 생성한다. 뮤턴트 세트를 생성한 후에는 테스트케이스가 프로그램의 변이된 부분을 검사하기 위해 생성된다. 모든 뮤턴트를 커버하는 테스트케이스를 생성하였다면 이론적으로 모든 가능한 에러를 해명한 것이다(하지만 실제는 뮤테이션 연산자에 의해 모델링된 에러로 커버리지가 한정됨).
이 패밀리에 속하는 기법들의 문제는 확장성(scalability)이다. 뮤테이션 연산자가 코드 라인당 다수의 뮤턴트를 생성할 수 있으며, 따라서 긴 프로그램의 경우 상당히 많은 수의 뮤턴트가 나온다. 이 패밀리 내의 다양한 기법들은 더 좋은 효율성을 달성하기 위해 표준 뮤테이션(또는 강력한 뮤테이션)의 확장성을 개선하는 것을 목표로 한다.
회귀 테스팅 기법(Regression testing techniques)
회귀 테스팅 기법은 프로그램의 기존 테스트스위트(test suite)에서 테스트를 선택적으로 재사용하여 회귀 테스트 비용을 줄인다. 선택적 회귀 테스팅 기법은 기존 테스트스위트에 있는 모든 테스트를 실행하는 “전체 재테스트(retest-all) 기법”과 다르다. 선택적 회귀 테스팅 기법은 축소된 테스트 서브집합을 선택하는 데 드는 비용이 회귀 테스팅 기법을 통해 생략된 테스트를 실행하는 데 드는 비용보다 적은 경우에만 전체 재테스트(retest-all) 기법 보다 더 경제적이다.
개선 테스팅 기법(Improvement testing techniques)
위에서 언급한 테스팅 기법 패밀리들을 보완하기 위해 다른 기법을 활용할 수 있으며, 이를 개선 테스팅 기법이라고 분류한다. 이 패밀리는 위에서 언급한 기법들에 의해 생성된 테스트케이스의 수를 줄이는 데 도움이 되는 기법이거나(최소화 기법), 또는 가능한 테스트 프로세스 초기에 프로그램 결함을 발견할 수 있도록 테스트케이스 집합의 순서를 설정하는 데 도움이 되는 기법이다(우선순위화 기법). 이 패밀리가 주로 회귀 테스팅 맥락에서 연구되었다.
각 패밀리에 속하는 기법들이 아래 표에 나와 있다.
패밀리 | 기법 | 설명 |
무작위 (Random) |
완전 무작위 | 테스트케이스가 무작위로 생성되고, 충분하다고 판단되면 생성을 중지한다. |
케이스 수로 안내 | 테스트케이스가 무작위로 생성되며, 주어진 케이스 수에 도달하면 생성을 중단한다. | |
에러 추측 | 프로그래밍에서 자주 발생하는 에러에 대한 사람(테스터)의 지식에 따라 테스트케이스를 생성한다. 모든 에러가 커버된 것처럼 보이면 생성을 중단한다. | |
기능적 (Functional) |
동등 분할 | 식별된 각 동등 클래스에 대해 하나의 테스트케이스를 생성한다. 테스트케이스가 클래스 내에서 무작위로 선택된다. |
경계값 분석 | 각 동등 클래스에 대해 여러 테스트케이스를 생성한다. 클래스 내부에 속하는 테스트케이스 1개와 클래스의 한계(또는 경계)를 커버하는 데 필요한 케이스를 필요한 만큼 많이 생성한다. | |
제어 흐름 (Control-flow) |
문장 커버리지 | 모든 프로그램 문장이 적어도 한 번은 실행되도록 테스트케이스를 생성한다. |
디시젼 커버리지 (브랜치 테스팅) |
모든 프로그램 디시젼이 참(true) 또는 거짓(false) 값을 갖도록 테스트케이스를 생성한다. | |
컨디션 커버리지 | 디시젼의 논리 표현식을 형성하는 모든 조건(프레디킷)이 참 또는 거짓 값을 갖도록 테스트케이스를 생성한다. | |
디시젼/컨디션 커버리지 | 컨디션 커버리지가 달성되었다고 해서 디시젼 커버리지가 항상 달성되는 것은 아니다. 디시젼 커버리지 달성을 위해 컨디션 커버리지에 의해 생성된 케이스들을 보충한다. | |
경로 커버리지 | 모든 프로그램 경로가 실행되도록 테스트케이스를 생성한다. 이 기준은 현실에서 적용(달성)할 수 없다. | |
데이터 흐름 (Data-flow) |
all-definitions | 각 변수 정의(definition)에 대해 이 변수를 적어도 한번은 사용하도록 테스트케이스를 생성한다. |
all-c-uses/some-p-uses | 각 변수 정의에서 해당 변수의 각 c-use(변수를 계산식에 사용)로 가는 경로가 최소 하나 이상 있도록 테스트케이스를 생성한다. 커버되지 않은 변수 정의가 있는 경우 p-use(변수를 조건식에 사용)를 사용한다. | |
all-p-uses/some-c-uses | 각 변수 정의에서 해당 변수의 각 p-use로 가는 경로가 최소 하나 이상 있도록 테스트케이스를 생성한다. 커버되지 않은 변수 정의가 있는 경우 c-use를 사용한다. | |
all-c-uses | 각 변수 정의에서 이 변수의 각 c-use로의 경로가 최소 하나 이상 있도록 테스트케이스를 생성한다. | |
all-p-uses | 각 변수 정의에서 이 변수의 각 p-use로의 경로가 최소 하나 이상 있도록 테스트케이스를 생성한다. | |
all-uses | 각 변수 정의에서 이 정의의 각 사용(use)으로 가는 경로가 최소 하나 이상 있도록 테스트케이스를 생성한다. | |
all-du-paths | 각 변수의 각 정의로부터 해당 정의의 각 사용으로 가는 가능한 모든 경로에 대해 테스트케이스를 생성한다. | |
all-dus | 각 변수의 각 정의로부터 해당 정의의 각 사용으로 가는 가능한 모든 실행(executable) 경로에 대해 테스트케이스를 생성한다. | |
뮤테이션 (Mutation) |
표준(강력한) 뮤테이션 | 해당 프로그래밍 언어에 대해 정의된 모든 뮤테이션 연산자를 적용하여 생성된 모든 뮤턴트를 커버하도록 테스트케이스를 생성한다. |
선택적(또는 제한된) 뮤테이션 | 프로그래밍 언어에 대해 정의된 일부 뮤테이션 연산자를 적용하여 생성된 모든 뮤턴트를 커버하도록 테스트케이스를 생성한다. 이는 선택된 연산자에 따라 선택적 변이를 발생시킨다. | |
약한 뮤테이션 | 해당 프로그래밍 언어에 대해 정의된 모든 뮤테이션 연산자를 적용하여 생성된 뮤턴트에 대해 주어진 퍼센트를 커버하도록 테스트케이스를 생성한다. | |
회귀 (Regression) |
무작위 | 테스트케이스가 기존 테스트스위트에서 무작위로 선택된다. |
Retest-all | 기존 테스트스위트의 모든 테스트를 실행한다. | |
Safe | 테스트 선택 알고리즘이 실행될 경우 변경된 프로그램의 오류를 드러낼 수 있는 기존 테스트스위트의 테스트를 제외하지 않는다. | |
변경에 기반 | 변경된 프로그램 컴포넌트와 변경으로 인해 영향을 받는 컴포넌트를 커버하도록 기존 테스트케이스를 선택하는 데 중점을 둔다. | |
데이터 흐름/ 커버리지 기반 |
변경에 의해 영향을 받는 데이터 인터액션을 실행하는 테스트를 선택한다. | |
개선 (Improvement) |
최소화(Minimization) | 생성된 테스트케이스의 수(number)를 줄인다. |
우선순위화 (Prioritization) |
생성된 테스트케이스 집합에서 순서(order)를 설정한다. |
'동적테스트활동별 > 테스트설계' 카테고리의 다른 글
상태 전이 분석에 의한 테스트케이스 도출 예 (0) | 2022.02.28 |
---|---|
동등 분할 및 경계값 분석에 의한 테스트케이스 도출 예 (1) | 2022.02.21 |
문서요약 - 조합식 테스트 설계 by Heymann (0) | 2019.12.16 |
테스트 설계 기법 개요 (0) | 2019.12.09 |
문서요약 - 유스케이스로부터 테스트케이스 개발하기 by Collard (0) | 2019.12.02 |