White Box Testing — 화이트 박스 테스팅 기법들

블랙 박스 테스팅이 입출력만으로 기능을 검증한다면, 화이트 박스 테스팅은 소스 코드의 내부 구조를 직접 들여다보며 논리적 경로를 검증한다. 코드의 어느 부분이 테스트되지 않았는지를 정량적으로 측정할 수 있다는 것이 핵심이다.

화이트 박스 테스팅이란?

화이트 박스 테스팅(White Box Testing)은 모듈의 원시 코드를 오픈 시킨 상태에서 수행하는 테스트이다. 원시 코드의 논리적인 경로들을 고려하여 테스트 케이스를 설계하는 방법이다.

  • 구조적 테스트: 설계된 절차에 초점을 두는 테스트 방법
  • 테스트 과정의 초기에 적용
  • 모듈 안의 작동을 직접 관찰
  • 원시 코드(모듈)의 모든 문장을 한 번 이상 실행함으로써 수행
  • 프로그램의 제어 구조에 따라 선택, 반복 등의 분기점 부분들을 수행

화이트 박스 테스팅 기법들

화이트 박스 테스팅 기법은 크게 기초 경로 검사제어 구조 검사로 나뉜다.

  • 기초 경로 검사(Base path testing): 대표적인 화이트 박스 테스트 기법. 테스트 케이스 설계자가 절차적 설계의 논리적 복잡성을 측정할 수 있게 해주는 기법이다. 테스트 측정 결과는 실행 경로의 기초를 정의하는 데 지침으로 사용한다.
  • 제어 구조 검사(Control structure testing):
    • 조건 검사(Condition testing): 프로그램 모듈 내에 있는 논리적 조건을 활용하는 테스트 케이스 설계 기법
    • 루프 검사(Loop testing): 프로그램의 반복(Loop) 구조에 초점을 맞춰 실시하는 테스트 케이스 설계 기법
    • 데이터 흐름 검사(Data flow testing): 프로그램에서 변수의 정의와 변수 사용의 위치에 초점을 맞춰 실시하는 테스트 케이스 설계 기법

커버리지 기법 비교

기법 설명 복잡도
문장 검증 기준(Statement coverage) 모든 문장을 한번씩 지나게 경로 선정 낮음
분기 검증 기준(Branch coverage) 분기의 모든 경로를 고려 중간
조건 검증 기준(Condition coverage) 분기 안의 모든 개별 조건을 고려 높음
분기/조건 검증 기준(Branch/Condition) 분기 + 조건 검증 결합 높음
다중 조건 검증 기준(Multiple condition) 모든 개별 조건의 조합 매우 높음
기본 경로 테스트(Basic path test) 전체적인 path로 복잡도 고려 매우 높음

방법 별로 복잡도와 소요 시간이 다르므로 테스트의 목적과 조건에 맞는 방법을 선택한다.

제어흐름 그래프

화이트 박스 테스트를 수행하려면 제어 흐름 그래프(Control Flow Graph)를 먼저 작성해야 한다. 소스 코드를 입력하여 코드의 실행 시작부터 종료 지점까지의 제어 흐름을 플로우 차트로 표현한 것이다.

제어흐름 그래프 예시

위 예시는 insertion_procedure 함수의 소스 코드를 제어흐름 그래프로 변환한 것이다. 각 문장에 번호(①~⑩)를 매기고, for문의 초기화(a), 조건(b), 증감(c)도 별도 노드로 표현한다.

문장 검증 기준 (Statement Coverage)

경로 기반 테스트 케이스를 선정하는 첫 번째 방법이다. 프로그램 내의 모든 문장이 최소한 한 번은 실행될 수 있는 테스트 데이터를 갖는 테스트 케이스를 선정한다.

예제: foo() 함수

foo(int X, int Y, int Z) {
    if (X > 1 && Y == 0) {
        Z = Z / X;
    }
    if (X == 2 || Z > 1) {
        Z = Z + 1;
    }
}

foo() 제어흐름 그래프

이 코드의 제어흐름 그래프에서 분기점은 (가) X > 1 and Y = 0과 (다) X = 2 or Z > 1 두 곳이다. 가능한 경로는 4가지이다:

번호 경로(가, 다) 가능 경로 만족 여부 이유
1 경로 1(T, T) a-c-e 만족 (가), (나), (다), (라) 문장을 모두 지나감
2 경로 2(T, F) a-c-d 불만족 (라) 문장을 안 지나감
3 경로 3(F, T) a-b-e 불만족 (나) 문장을 안 지나감
4 경로 4(F, F) a-b-d 불만족 (나), (라) 문장을 안 지나감

문장 검증 기준을 만족하는 경로는 경로 1(T, T) 뿐이다. 이 경로에 해당하는 테스트 데이터는 X=2, Y=0, Z=3이며, 출력값은 Z=2이다.

문장 검증 기준의 문제점

첫 번째 조건문에서의 문제: 원래는 and인데 실수로 or로 코딩한 경우, 검증 기준 방법으로는 오류를 발견하지 못한다. and인 경우와 or인 경우 모두 입력값 (X=2, Y=0, Z=3)에서 (나) 문장을 지나가기 때문이다.

두 번째 조건문에서의 문제: Z>1 식을 Z>0으로 잘못 코딩해도 오류를 발견하지 못한다. or의 특성이 둘 중 하나만 만족하면 다른 조건식은 결과에 영향을 주지 않기 때문이다.

이러한 문제를 해결하기 위해 → 분기 검증 기준이 필요하다.

분기 검증 기준 (Branch Coverage)

모든 분기를 적어도 한 번씩은 거쳐 가도록 경로를 선정하는 방법이다. 조건문에 대해 T와 F가 최소한 한 번은 실행되는 입력 데이터를 테스트 케이스로 사용한다.

  • 분기 시점 또는 합류 위치에서 조건과 관련된 오류를 발견할 가능성이 높다
  • if 문의 경우 참과 거짓의 두 경로가 각각 한 번씩 선정되어야 한다
  • switch 문에서는 모든 case 문과 default 문이 선정되어야 한다
  • for 문이나 while 문에서는 적어도 한 번 루프의 내부가 실행되어야 한다

네 개의 경로 중 하나만으로는 분기 검증 기준을 만족시키지 못하므로, 두 개의 경로를 묶어서 분기 검증 기준을 만족시킬 수 있는 경우를 찾는다.

가능한 조합: (1,4) 또는 (2,3)

  • 경로 (1,4): 경로 1 (T,T) + 경로 4 (F,F) → (가)에서 T와 F, (다)에서 T와 F 모두 테스트
  • 경로 (2,3): 경로 2 (T,F) + 경로 3 (F,T) → (가)에서 T와 F, (다)에서 F와 T 모두 테스트

분기 검증 기준의 문제점 — or 연산

경로 (1,4)를 선택한 경우, 문장 (다)에서 Z>1Z<1로 잘못 코딩해도 오류를 발견하지 못한다. 이유는 개별 조건식이 or로 연결되어 있어 둘 중 하나라도 T이면 다른 식이 무엇이든 관계없이 조건문의 결과 값에 영향을 주지 않기 때문이다.

분기 검증 기준의 문제점 — and 연산

if (score >= 90 && report >= 90) 같은 조건에서 report >= 90report < 90으로 잘못 코딩해도 발견하지 못하는 경우가 있다. 두 개별 조건식이 and로 연결되어 있어 둘 중 하나라도 F이면 다른 식이 무엇이든 관계없이 조건문의 결과 값에 영향을 주지 않기 때문이다.

이러한 문제를 해결하기 위해 → 조건 검증 기준이 필요하다.

조건 검증 기준 (Condition Coverage)

조건문 내의 개별 조건식에 대하여 각각 T와 F인 경우를 최소한 한 번씩 수행한다.

분기 검증 기준이 조건문 전체의 T/F만 고려했다면, 조건 검증 기준은 조건문을 구성하는 개별 조건식 각각에 대해 T와 F를 모두 테스트한다.

블랙 박스 vs 화이트 박스

구분 블랙 박스 화이트 박스
관점 외부(사용자) 내부(개발자)
기반 요구사항 명세 소스 코드
적용 시점 테스트 후반부 테스트 초기
장점 사용자 관점의 기능 검증 코드 내부 논리 검증, 커버리지 측정 가능
단점 내부 로직 미검증 기능적 요구사항 누락 가능
대표 기법 동등 분할, 경계값 분석 문장/분기/조건 검증