본문으로 건너뛰기
중급약 40분

구조 기반 테스트 계산 — 문장·결정·조건·결정/조건·다중 조건·MC/DC의 최소 테스트 케이스 구하기

CSTS 단답형에서 가장 자주 나오는 구조 기반 계산을 손으로 푼다. 제어 흐름 그래프와 기본 블록, 결정과 조건의 정의(DO-178), 여섯 가지 커버리지의 달성 조건과 포함 관계, 커버리지 비율 계산식, 조건 커버리지가 결정 커버리지를 보장하지 못하는 반례, MC/DC가 n+1개로 끝나는 이유, 경로가 주어졌을 때 커버리지를 계산하는 법을 예제와 연습 문제로 익힌다.

  • #CSTS
  • #구조기반테스트
  • #문장커버리지
  • #결정커버리지
  • #조건커버리지
  • #MCDC
  • #제어흐름그래프

개념

왜 일부 경로만 테스트하는가

가장 이상적인 구조 기반 테스트는 모든 경로 를 한 번씩 실행하는 것이다. 하지만 반복문 안에 분기가 하나만 있어도 반복 횟수 n에 따라 경로가 2^n 개로 늘어난다(n = 20이면 백만 개 이상). 그래서 문장·결정·조건 같은 기준 을 정해 경로의 일부만 고른다. 이 기준이 커버리지다.

제어 흐름 그래프와 기본 블록

  • 노드 — 기본 블록(중간에 분기가 없이 한 번에 실행되는 문장 묶음) 또는 결정
  • 간선 — 실행 흐름
  • 결정 노드 — 나가는 간선이 2개 이상인 노드

결정과 조건 — DO-178의 정의

용어정의예 if (x > 0 && y <= -3)
조건(Condition)논리 연산자(&&, ||)를 포함하지 않는 불리언 식x > 0, y <= -3 각각
결정(Decision)조건들이 0개 이상의 논리 연산자로 묶인 불리언 식x > 0 && y <= -3 전체

조건이 하나뿐인 결정은 그 자체가 조건이다. 같은 조건이 결정에 두 번 나오면 별개의 조건 으로 센다. 가이드는 switch 처럼 참·거짓이 아닌 여러 값을 갖는 결정도 결정으로 다룬다.

여섯 가지 커버리지

커버리지달성 조건비율 계산
문장(Statement)실행 가능한 모든 문장을 1회 이상실행한 문장 ÷ 전체 문장
결정(Decision, = 분기)모든 결정의 결과 가 참·거짓을 각각 1회 이상실행한 결정 결과 ÷ (결정 수 × 2)
조건(Condition)모든 조건 이 참·거짓을 각각 1회 이상나온 조건 값 ÷ (조건 수 × 2)
결정/조건(Decision/Condition)결정 커버리지 + 조건 커버리지를 동시에
다중 조건(Multiple Condition)한 결정 안 조건 값의 모든 조합조건 n개면 2^n
MC/DC(변형 조건/결정)결정/조건 + 각 조건이 다른 조건을 고정한 채 단독으로 결정 결과를 바꿈 을 보임보통 n + 1개

포함 관계(강한 쪽이 약한 쪽을 보장)는 다음과 같다.

다중 조건  ⇒  MC/DC  ⇒  결정/조건  ⇒  결정  ⇒  문장
                          ⇓
                         조건

조건 커버리지는 결정 커버리지를 보장하지 않는다. 이것이 가장 자주 나오는 함정이다. 반대로 결정 커버리지도 조건 커버리지를 보장하지 않는다. 둘을 함께 요구하는 것이 결정/조건이다.

한 함수로 여섯 가지를 모두 계산하기

void f(int x, int y) {
  if (x > 0 && y > 0)   // 결정 D, 조건 A: x > 0, 조건 B: y > 0
    s1;
  s2;
}
커버리지최소 TC예 (x, y) → (A, B) → D개수
문장D가 참이 되는 한 개면 s1·s2 모두 실행(1, 1) → (T, T) → T1
결정D 참 1개, 거짓 1개(1, 1) → T / (0, 1) → F2
조건A·B가 각각 T·F(1, 0) → (T, F) → F / (0, 1) → (F, T) → F2
결정/조건위 둘을 동시에(1, 1) → (T, T) → T / (0, 0) → (F, F) → F2
다중 조건모든 조합 TT·TF·FT·FF4개4
MC/DCA의 단독 영향 (TT vs FT), B의 단독 영향 (TT vs TF)(T, T), (F, T), (T, F)3

조건 커버리지 행을 보자. 두 TC 모두 결정이 거짓 이라 s1이 한 번도 실행되지 않는다. 조건 커버리지 100%인데 결정 커버리지 50%, 문장 커버리지도 100%가 아니다. 시험은 이 표를 그대로 묻는다.

단축 평가 주의 — C·Java의 && 는 A가 거짓이면 B를 평가하지 않는다. 실행 기준으로 보면 (0, 1) 에서 B는 평가되지 않으므로 B의 T가 "나왔다"고 보기 어렵다. 가이드 예제는 대개 값 기준(진리값) 으로 계산하지만, 문제에 "단축 평가를 고려하여"라는 말이 있으면 평가된 조건만 센다.

MC/DC는 왜 n + 1인가

조건 n개짜리 결정에서 각 조건마다 "그 조건만 바꿔 결과가 뒤집히는 TC 쌍"이 필요하다. 쌍을 서로 공유하면 n + 1개로 끝난다.

  • AND(&&) n개 — 전부 T인 1개 + 각 조건 하나만 F인 n개 = n + 1
  • OR(||) n개 — 전부 F인 1개 + 각 조건 하나만 T인 n개 = n + 1

예: A || B || C 의 MC/DC 집합은 (F,F,F), (T,F,F), (F,T,F), (F,F,T) 4개다. 다중 조건은 2^3 = 8개다. 조건이 많을수록 MC/DC가 다중 조건보다 압도적으로 싸다 — 그래서 항공(DO-178C Level A)·자동차(ISO 26262 ASIL D)가 MC/DC를 요구한다.

결정이 여러 개일 때의 결정 커버리지

결정이 순차로 여러 개면 TC 하나가 여러 결정의 결과를 동시에 덮을 수 있다.

if (a > 0) s1;      // D1
if (b > 0) s2;      // D2

(a, b) = (1, 1)과 (0, 0) 두 개로 D1·D2 모두 참·거짓을 덮는다 — 결정 수가 2라고 TC가 4개 필요한 것이 아니다. 최소 TC 수는 결정 하나가 갖는 결과의 최대 개수 와 같거나 그보다 크다. 결정이 중첩 되어 있으면 다르다.

if (a > 0) {        // D1
  if (b > 0) s1;    // D2 — D1 이 참일 때만 도달
  else s2;
} else s3;

D2의 참·거짓은 D1이 참인 경로에서만 나오므로 (1, 1), (1, 0), (0, 임의) 세 개가 필요하다.

경로가 주어졌을 때 커버리지 계산

단답형은 제어 흐름 그래프와 실행 경로를 주고 비율을 묻는다. 예시 그래프(노드 = 기본 블록):

      1
      │
      2 ──(F)──▶ 4
      │(T)       │
      3          │
      │          │
      5 ◀────────┘
      │
      6 ──(F)──▶ 8
      │(T)       │
      7          │
      │          │
      9 ◀────────┘

결정은 2와 6 두 개, 결정 결과는 4개(2T·2F·6T·6F), 노드는 9개다.

  • 경로 1-2-3-5-6-8-9 하나를 실행하면 — 노드 7개/9개 실행(4·7 미실행) → 문장 7/9 ≈ 77.8%, 결정 결과 2T·6F 2개/4개 → 결정 50%
  • 경로 하나를 더해 1-2-4-5-6-7-9 를 실행하면 → 문장 9/9 = 100%, 결정 4/4 = 100%
  • 결정 100%를 위한 최소 TC는 2 다. 순환 복잡도는 분기 노드 2 + 1 = 3 이므로 기본 경로 테스트라면 3개(예: T,T, F,F, T,F)가 필요하다

기본 경로 테스트

순환 복잡도 V(G)만큼의 선형 독립 경로 를 고르고 각 경로를 실행하는 TC를 만든다. 기본 경로 테스트는 결정 커버리지를 보장한다. 루프가 있으면 "0회·1회 반복"이 서로 다른 독립 경로가 된다.

실무에서 왜 필요한가

커버리지 도구(JaCoCo·Istanbul·gcov)는 숫자를 주지만 어떤 기준의 숫자인지 는 사람이 읽어야 한다. JaCoCo의 "Branches"는 결정 커버리지에 가깝고, 조건 단위 정보는 일부만 보여 준다. 그래서 "분기 85%" 리포트를 보고 "조건 하나가 항상 참으로만 평가된 결정이 남아 있을 수 있다"고 질문할 수 있어야 한다 (s3-m53-l01). 안전 필수 프로젝트에서는 MC/DC 증거를 감사에 내야 하는데, TC 쌍을 직접 설명할 수 있어야 감사 질의를 넘긴다(s2-m35 모듈).

실습 과제

과제 1 — 표 채우기 (10분)

if (p || q) 에 대해 문장(분기 안에 문장 하나)·결정·조건·결정/조건·다중 조건·MC/DC 최소 TC를 진리값으로 적는다. 정답: 문장 1 (T,·) / 결정 2 (T,F), (F,F) / 조건 2 (T,F), (F,T) — 이때 결정은 둘 다 참이라 결정 50% / 결정/조건 2 (T,T), (F,F) / 다중 4 / MC/DC 3 (F,F), (T,F), (F,T).

과제 2 — 조건 커버리지 비율 (6분)

if (a > 5 && b < 3 && c == 0) 에 TC 세 개 (a, b, c) = (6, 1, 0), (6, 4, 0), (2, 1, 1)을 실행했다. 값 기준으로 조건 커버리지와 결정 커버리지를 구한다. 풀이: a > 5 는 T·T·F → T·F 모두, b < 3 은 T·F·T → 모두, c == 0 은 T·T·F → 모두 → 조건 6/6 = 100%. 결정은 T·F·F → 참·거짓 모두 → 100%.

과제 3 — MC/DC 쌍 짓기 (8분)

(A && B) || C 의 MC/DC 최소 집합을 구한다. 힌트: C = F로 고정하고 A·B를 AND로 다룬 뒤, C를 혼자 바꾸는 쌍을 하나 더한다. 정답 예: (T,T,F) T, (F,T,F) F, (T,F,F) F, (F,T,T) T — 4개(n + 1).

과제 4 — 경로와 커버리지 (8분)

위 예시 그래프에서 경로 1-2-4-5-6-8-9 하나만 실행했을 때 문장·결정 커버리지를 구한다. 정답: 노드 1·2·4·5·6·8·9 = 7/9 ≈ 77.8%, 결정 결과 2F·6F = 2/4 = 50%.

자가 체크리스트

  • 조건과 결정의 정의를 DO-178 기준으로 말할 수 있다
  • 여섯 커버리지의 포함 관계를 그릴 수 있다
  • 조건 커버리지 100%인데 결정 커버리지가 50%인 예를 만들 수 있다
  • AND·OR 결정의 MC/DC 집합을 n + 1개로 구할 수 있다
  • 순차 결정과 중첩 결정에서 결정 커버리지 최소 TC 수가 다른 이유를 안다
  • 그래프와 경로가 주어지면 문장·결정 커버리지 비율을 계산할 수 있다
  • 단축 평가가 계산에 미치는 영향을 설명할 수 있다

흔한 실수

  • 조건 커버리지 ⇒ 결정 커버리지라고 고른다. 대표 함정이다. 조건 커버리지는 결정 결과를 보장하지 않는다
  • 결정 수 × 2를 최소 TC 수로 쓴다. 순차 결정은 TC 하나가 여러 결정을 동시에 덮는다
  • MC/DC를 2n개로 계산한다. 쌍을 공유하면 n + 1개다
  • 분모를 결정 수로 쓴다. 결정 커버리지의 분모는 결정 결과 수(결정 수 × 2)다
  • 문장 커버리지 100%면 결정도 100%라고 생각한다. else 가 없는 if 는 참 경로 하나로 문장 100%가 되지만 거짓 결과는 실행되지 않는다

참고 자료

  • TTA, 『CSTS 가이드 — 일반등급』 9장 구조 기반 테스트 — 제어 흐름 그래프, 문장·결정·조건·결정/조건·다중 조건 테스트
  • RTCA DO-178C, Software Considerations in Airborne Systems and Equipment Certification, 2011 — 조건·결정·MC/DC 정의(가이드는 DO-178B 문장을 인용)
  • Hayhurst, K. J. et al., A Practical Tutorial on Modified Condition/Decision Coverage, NASA/TM-2001-210876, 2001
  • ISO/IEC/IEEE 29119-4:2021 Test techniques — 5.3 구조 기반 기법
  • 이 커리큘럼 안: s1-m03-l07 「구조 기반 기법 — 구문·분기·조건·MC/DC 커버리지」, s1-m03-l10 「순환 복잡도로 최소 테스트 케이스 수 계산하기」, s3-m53-l01 「커버리지 도구 실습」

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

MC/DC — 변형 조건·결정 커버리지
조건이 여러 개 붙은 판단문에서, 각 조건이 혼자서 결과를 바꾸는 경우까지 모두 확인했는지 재는 기준.
TC — 테스트 케이스
무엇을 어떻게 해보고 무엇이 나와야 하는지를 한 건으로 적어 둔 것. 시험 문제 한 문항에 해당한다.
DO-178C — 항공 소프트웨어 인증 지침
비행기에 들어가는 소프트웨어를 어떻게 만들고 증명해야 하는지 정한 문서.
ISO — 국제표준화기구
여러 나라가 모여 "이건 이렇게 하자"를 문서로 정하는 단체. 그 문서 자체를 번호로 부른다.
ASIL — 자동차 안전 완전성 수준
자동차 분야의 위험 등급. A부터 D까지이고 D가 가장 엄격하다.
TTA — 한국정보통신기술협회
국내 정보통신 표준을 만들고 시험·인증도 하는 기관.
ISO/IEC/IEEE — 세 단체 공동 표준
세 국제 단체가 함께 낸 표준이라는 표시.

용어집 전체 보기