[SE] 9장 테스팅

9장 테스팅

9.1 테스팅 기초


(1) 오류(Error), 결함(Defect, Fault, Bug), 고장 (Failure)

 - 오류 -> 결함 -> 고장

(2) 기능적 테스트(또는 블랙박스 테스트) vs. 구조적 테스트(또는 화이트박스 테스트)
소프트웨어 테스팅은 기능적 테스트(functional test)와 구조적 테스트(structural test)로 나눈다. 
기능적 테스트는 프로그램에 테스트 데이터를 입력하여 실행한 결과가 예상대로 산출되는가를 살펴보는 
방법이다. 기능적 테스트는 주로 명세서를 기반으로 하기 때문에 명세 기반 테스트(Spec-based test)라
부르기도 한다. 그리고 테스트 설계시에 코드 내용을 고려하지 않는다는 점에서 블랙박스 테스트(black
box test)라고도 하며, 겉으로 드러나는 행위를 조사한다는 점에서 행외적 테스트(Behavioral test)라고도
부른다. 

구조적 테스트는 구현한 코드를 테스트 설계의 기반으로 사용하는 코드 기반 테스트라 부른다. 코드 기반
테스트는 코드 내부의 구조를 참고하면서 테스트를 설계한다. 따라서 화이트 박스 테스트(white box test)라
부르기도 한다. 코드 기반 테스트는 테스트 데이터를 입력하여 테스트를 수행한 다음 산출되는 출력의
정확성을 조사하느 점에서 블랙박스 테스트와 방법상에는 차이가 없다. 그러나 구조적 테스트에서 사용하는
테스트 데이터는 코드의 구조나 게산 논리를 고려하여 도출하므로 코드의 구조나 세부 계산 논리상의
문제점을 추가적으로 확인할 수 있다는 잇점이 있다.

그러나 구조적 테스팅을 해도 코드 내의 결함을 찾아낼 수 없는 경우도 존재한다. 예를 들어, 프로그래머가
명세서를 잘못 읽거나 요구사항을 빠뜨린 경우가 그러하다. 이러한 경우는 명세서와 관련된 실수이므로 
명세서를 기반으로 하는 기능적 테스트로 구조적 테스를 보완해야 한다.



9.2 Black-box testing

 - 스펙에 기반한 테스팅
 
 - 테스트 케이스 생성 방법
   1) Equivalence partitioning
   2) Boundary-value analysis
   3) Cause-effect graph
   ...
   4) Pair-wise testing
   5) Error guessing
   6) State-based testing

Equivalence partitioning 예제

 - 스펙
   1) 나이는 0~30을 가정
   2) 나이가 10세 이하이면 입장 불가
   3) 나이가 10~17이면 부모 동반
   4) 나이가 18~30이면 혼자도 입장 가능

 - Exhaustive testing을 할 경우 31가지 경우

 - 입력(나이 범위)을 Equivalence Class (EC)로 분류

   1) EC1: 0 <= 나이 <= 10
   2) EC2: 10 <= 나이 <= 17
   3) EC3: 18 <= 나이 <= 30

 - 각 EC에서 하나의 원소를 선택하면 전체 테스트할 경우를
   31가지에서 3가지로 줄일 수 있음

   : 각 클래스의 모든 원소는 "equivalent" 하다는 가정


 - 유효한 입력에 대한 클래스와 별도로 유효하지 않은 입력도 고려

   4) Invalid EC (IEC)1 : -10   (0 미만)
   5) IEC2 : 35 (30 초과)
   6) 10.5 또는 "abc"   (나이를 표현한 정수 타입와 다른 타입의 입력)

   유효하지 않은 입력 = 동일 타입의 값들 중 범위를 벗어나거나 타입이 다른 값들

Boundary value analysis

 - EC의 경계에 있거나 가까운 값을 선택하여 테스트
   (EC 안의 값들 중 임의로 선택하지 않고)

   : EC1 (0 <= 나이 <= 10)에서 0, 10 -1, 1을 선택
   : EC2 (10 <= 나이 <= 17)에서 16, 17을 선택
   : EC3 (18 <= 나이 <= 30)에서 18, 19, 29, 30, 31을 선택

 - 변수가 둘 이상의 경우 각 변수의 boundary value들을 조합

   (교재 그림 9.4)


Cause-Effect Graph

 - 입력 조건의 조합을 표현하는 테스트 케이스를 만드는 방법 
   
   : (기본 아이디어) 출력 "effect"는 입력 "causes"의 조합과 연관있다.

   : 앞의 두 방법은 각 입력에 대해 독립적으로 테스트케이스를 만들었음.
      여러 입력들의 조합을 고려하여 테스트케이스를 만드는 시도는 미흡.

 - 교재 그림 9.5 예제로 부터 표 9.3의 각 컬럼에 해당하는 테스트 케이스 생성

 - Cause-Effect graph는 어떻게 만들까?

   : 스펙을 분석하여 그래프를 만들어야 함  (명확한 방법론이 있는 것은 아님)



9.3 White-box testing

 - 프로그램의 구조에 기반한 테스팅
 
 - 프로그램을 테스팅한 범위(Coverage)에 기반한 테스트 케이스 생성
   1) Statement coverage (cf. Node coverage)
   2) Decision/Branch coverage (cf. Edge coverage)
   3) Codition Coverage 
   4) Decision/Condition coverage
   5) Multiple-condtion coverage
   6) Modified Decision/Condition coverage (MCDC)

프로그램 구조 표현
 - 제어 흐름 그래프 (Control flow graph)
    : (슬라이드 참고)
 
Statement coverage
 - (슬라이드 참고)
 - TC1, TC2 두 개의 테스트케이스로 S1 ~ S4 문장을 적어도 한번씩 실행한다.

Branch coverage (Decision coverage)
 - (슬라이드 참고)
 - TC1에 의해 D1이 False인 경우와 D2가 False인 경우를 실행하고
   TC2에 의해 D1이 True인 경우와 D2가 True인 경우를 실행

Condition coverage vs. Branch (Decision) coverage
 - Condition : 가장 작은 단위의 조건
 - Decision : 조건식을 참 또는 거짓으로 판단함
 - Condition coverage
    : 각 condition이 True와 False가 두 가지 모두 실행하도록 Test suite를 작성
 - (슬라이드 참고)
 - TC1, TC2를 포함한 Test suite는 
   Condition coverage를 만족하지만 Decision coverage를 만족하지 못함
   D1이 True인 경우를 실행하지 못함

Condition/Decision coverage
 - 두 coverage 조건을 모두 만족하는 Test suite
 - (슬라이드 참고)

Multiple-Condition coverage
 - 각 조건의 모든 조합을 테스트하는 Test suite
 - (슬라이드 참고)

Modified Condition Decision Coverage (MCDC)
 - Multiple-condition coverage의 경우 세밀한 테스트를 하는 장점이 있으나
   너무 많은 TC가 필요한 단점이 있다. 2^(# of conditions)

 - MCDC TC는 Decision에 독립적으로 (다른 condition과 조합하지 않고) 
   영향을 미치는 Condition이 있는 테스트케이스
 - MCDC는 동일한 정도로 세밀하게 테스트하지만 TC 수를 크게 줄일 수 있는 방법
 - (슬라이드 참고)

 - A and B and C에 대한 MCDC coverage를 만족하는 test suite

    A,B,C = T,T,T     T,T,F,     T,F,T    F,T,T

    T,T,T의 Decision T, F,T,T의 Decision은 F 따라서 B,C의 도움없이
    조건 A를 T와 F로 변경하면 A and B and C의 Decision이 변경됨.

    F,F,T는 B,C를 그대로 두고 A를 변경해도, A,C를 그대로 두고 B를 변경해도
    A,B를 그대로 두고 C를 변경해도 Decision이 변경되지 않는다. 따라서
    A,B,C 각 조건은 독립적으로 Decision에 영향을 주지 않는다.