423. 결정 커버리지 (Decision Coverage)

핵심 인사이트 (3줄 요약)

  1. 본질: 결정 커버리지(Decision Coverage)란 화이트박스 테스트에서 테스트 케이스가 분기문(Decision Point)의 모든 결과(참/거짓)를 최소 한 번씩 실행하도록 검증하는 지표이다. 분기 커버리지(Branch Coverage)라고도 한다.
  2. 가치: 구문 커버리지보다 더 엄격하여, if, while, for 등의 분기문에서 모든分支를 테스트하는지를 확인함으로써,片側分支만 테스트되는 상황을 방지할 수 있다.
  3. 융합: 결정 커버리지는 DO-178B/C 항공기 소프트웨어 표준에서 요구하는 커버리지 수준이며, 자동비행 시스템 등 안전 중요(Safety-Critical) 소프트웨어 검증에 필수적으로 활용된다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

  • 개념: 결정 커버리지는 분기문(if, while, for, switch 등)에서 가능한 모든 결과(참과 거짓)가 최소 한 번씩 실행되었는지를 측정하는 지표이다. 결정 커버리지율(%)은 "실행된 결정 결과 수 / 전체 결정 결과 수 × 100"으로 계산한다.

  • 필요성: 구문 커버리지는 모든 문장이 실행되면 100%가 되지만, 분기문의片側分支만 실행되어도 모든 문장이 실행된 것이 된다. 예를 들어 if (condition) { A } else { B }에서 condition이 항상 참이면 A만 실행되고 B는 실행되지 않지만, 구문 커버리지는 100%이다. 결정 커버리지는 이러한 片側만 테스트되는 상황을 방지한다.

  • 결정(Decision)의 정의: 결정은 분기문을 통해 생성되는 논리적 결과이다. if, while, for, do-while, switch, ?: (삼항 연산자) 등이 결정에 해당한다. 각 결정은 최소 2개의 결과(참/거짓, 혹은 해당 분기 수)를 갖는다.

  • 비유: 결정 커버리지는 **'교차로 양쪽 진행 검증'**과 같다. 교차로에서 좌회전과 우회전(두 branch)이 있는데, 항상 좌회만 한다면(片側만 테스트) 우회전 경로의 안전성을 확인하지 못한다. 양쪽 모두 한 번씩 진행해봐야 교차로 전체의 안전性を確認한 것이다.

  • 등장 배경 및 발전 과정:

    1. 1970년대: 구조적 테스트 기법의 일환으로 결정 커버리지 개념 도입
    2. 1990년대: DO-178B 표준에서 안전 중요 소프트웨어에 필수적인 커버리지 수준으로 규정
    3. 현재: 자동驱动程序, 항공기 제어 시스템 등 안전 중요 시스템 테스트의 핵심 지표
  • 섹션 요약 비유: 결정 커버리지는 **'배낭旅行 양쪽 경로 확인'**과 같다. 산책길에서 왼쪽 길과 오른쪽 길(두 branch)이 갈라지고, 항상 왼쪽으로만 가면 오른쪽 길에何があるか分からない。양쪽 모두 한 번씩 걸어보면"오른쪽 길은 험난하지만 경치가 좋다"는 것을알 수 있다. 테스트도 마찬가지로 두分支 모두 테스트해야 시스템 전체를把握할 수 있다.


Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

결정 커버리지 계산

[결정 커버리지 계산]

  코드:
  1: function checkAge(age):
  2:     if (age >= 18):          // 결정 1
  3:         return "성인"
  4:     else:
  5:         return "미성년"
  6:
  7:     if (age >= 65):          // 결정 2
  8:         return "경로优惠"
  9:     else:
  10:        return "일반"
  11:
  12:    return "완료"

  TC-01: age = 20 → "성인", "일반"

  ┌─────────────────────────────────────────────────────────────────┐
  │                    결정 커버리지 분석                                          │
  ├─────────────────────────────────────────────────────────────────┤
  │                                                                  │
  │   결정 1 (age >= 18):                                             │
  │   ✓ 참 (age = 20) → TC-01에서 Covered                            │
  │   ✗ 거짓 (age < 18) → TC-01에서 미Covered                         │
  │                                                                  │
  │   결정 2 (age >= 65):                                             │
  │   ✓ 거짓 (age < 65) → TC-01에서 Covered                            │
  │   ✗ 참 (age >= 65) → TC-01에서 미Covered                         │
  │                                                                  │
  │   결정 커버리지 = 2 / 4 × 100 = 50%                               │
  │                                                                  │
  │   ※ 100% 결정을 위해 TC-02: age = 70 추가 필요                     │
  │                                                                  │
└─────────────────────────────────────────────────────────────────┘

[다이어그램 해설] TC-01 (age=20)만 실행하면 결정 1은 참分支만, 결정 2는 거짓分支만 Covered 된다. 두 결정 모두 두分支를Cover하려면 TC-02 (age=70)를 추가하여 결정 1의 거짓分支와 결정 2의 참分支를 Covered 해야 한다.

구문 커버리지 vs 결정 커버리지

[구문 커버리지 vs 결정 커버리지]

  코드:
  if (condition):
      doSomething()

  ┌─────────────────────────────────────────────────────────────────┐
  │                    커버리지 비교                                             │
  ├─────────────────────────────────────────────────────────────────┤
  │                                                                  │
  │   TC: condition = true                                          │
  │   구문 커버리지: 100% (모든 문장 실행)                           │
  │   결정 커버리지: 50% (참만 Covered, 거짓 미Covered)               │
  │                                                                  │
  │   TC: condition = false                                         │
  │   구문 커버리지: 0% (if 내부 문장 미실행)                        │
  │   결정 커버리지: 50% (거짓만 Covered, 참 미Covered)               │
  │                                                                  │
  │   TC: condition = true + false                                 │
  │   구문 커버리지: 100%                                           │
  │   결정 커버리지: 100%                                           │
  │                                                                  │
└─────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 이 예시에서 구문 커버리지와 결정 커버리지의 차이를 보여준다. condition = true만 테스트하면 구문 커버리지는 100%이지만, if문의 거짓分支는 실행되지 않았으므로 결정 커버리지는 50%이다. 참과 거짓을 모두 테스트해야 결정 커버리지 100%를 달성한다.

복합 조건문의 결정 커버리지

[복합 조건문의 결정 커버리지]

  코드:
  if (A > 0 and B > 0):
      result = 1
  else:
      result = 0

  ※ "A > 0 and B > 0" 전체가 하나의 결정
  ※ 전체 조건의 결과(참/거짓)만 검증

  TC-01: A = 5, B = 5 → result = 1 (참 Covered)
  TC-02: A = -1, B = 5 → result = 0 (거짓 Covered)

  결정 커버리지 = 2 / 2 × 100 = 100%

  ※ 개별 조건 A > 0, B > 0의 독립적인 참/거짓은 검증하지 않음
  ※ 이것은 조건 커버리지(Condition Coverage)의 영역

Ⅲ. 구현 및 실무 응용 (Implementation & Practice)

결정 커버리지 측정 도구

[결정 커버리지 도구]

  Java: JaCoCo (branchCoverage)
  JavaScript: Istanbul, Jest --coverage --collectCoverageFrom
  Python: Coverage.py (branch=True)
  C/C++: gcov, LLVM Source-based Coverage

  ┌─────────────────────────────────────────────────────────────────┐
  │                    커버리지 보고서 예시                                      │
  ├─────────────────────────────────────────────────────────────────┤
  │                                                                  │
  │   파일              │ 라인 │ 분기 │ 분기 커버리지 │                   │
  │   ────────────────────────────────────────────────────────────  │
  │   UserService.java  │ 95%  │ 88%  │    88%       │                │
  │   OrderService.java │ 82%  │ 75%  │    75%       │                │
  │   PaymentService.java│100% │100%  │   100%       │                │
  │   ────────────────────────────────────────────────────────────  │
  │   합계              │ 92%  │ 85%  │    85%       │                │
  │                                                                  │
└─────────────────────────────────────────────────────────────────┘

DO-178B/C 표준에서 결정 커버리지

[DO-178B/C에서 결정 커버리지 요구사항]

 航空機 소프트웨어 개발에서 중요한 개념:

  - DO-178B: 소프트웨어 Considerations in the Development of
    Airborne Electric Electronic Systems for Certification

  - MC/DC (Modified Condition/Decision Coverage)가 최상위 수준으로 요구
  - 결정 커버리지는 MC/DC보다 낮은 수준으로 분류

  ┌─────────────────────────────────────────────────────────────────┐
  │                    DO-178B 커버리지 수준                                    │
  ├─────────────────────────────────────────────────────────────────┤
  │                                                                  │
  │   수준    │ 설명                         │ 적용 분야               │
  │   ────────────────────────────────────────────────────────────  │
  │   DC     │ 결정 커버리지                  │ 일부 안전 덜 중요한 시스템  │
  │   MC/DC  │ 변경 조건/결정 커버리지 (고급)  │ 안전 중요 시스템 (항공기)  │
  │   CC     │ 완전한 조건 커버리지           │ 특수 요구사항           │
  │                                                                  │
└─────────────────────────────────────────────────────────────────┘

테스트 케이스 설계

[결정 커버리지 달성 테스트 케이스 설계]

  코드:
  function processOrder(order, isPremium):
      if (order.amount > 100):
          discount = 10
      else:
          discount = 0

      if (isPremium):
          discount += 5

      return discount

  결정 커버리지 100% 달성:
  TC-01: order.amount=150, isPremium=true  → discount=15
         (결정1: 참, 결정2: 참)
  TC-02: order.amount=50, isPremium=false → discount=0
         (결정1: 거짓, 결정2: 거짓)

  ※ 2개 테스트로 2개 결정 × 2개 결과 = 4개 모두 Covered

Ⅳ. 품질 관리 및 테스트 (Quality & Testing)

결정 커버리지 장단점

[결정 커버리지 장단점]

  장점:
  ├─ 구문 커버리지보다 엄격하여 테스트 충분성 향상
  ├─ 분기문의片側만 테스트되는 상황 방지
  ├─ 안전 중요 시스템의 기본적인 커버리지 지표
  ├─ 구현이 비교적 간단하여 도구 지원良好
  └─ 분기문 기반 결함 발견에 효과적

  단점:
  ├─ 복합 조건에서 개별 조건 상호작용 검증 불가
  ├─ 결정 커버리지 100%도 모든 결함을 발견하지 못함
  ├─ 순환을 포함한 경로 커버리지는 제공하지 않음
  └─ 더 엄격한 안전 시스템에서는 MC/DC 필요

커버리지 수준별 비교

[커버리지 수준별 요구사항]

  구문 < 결정 < 조건 < MC/DC

  ┌─────────────────────────────────────────────────────────────────┐
  │                    커버리지 수준 트리                                         │
  ├─────────────────────────────────────────────────────────────────┤
  │                                                                  │
  │   구문 커버리지: 모든 문장 실행                                   │
  │       │                                                        │
  │       └── 결정 커버리지: 모든 분기(참/거짓) 실행                   │
  │               │                                                │
  │               └── 조건 커버리지: 모든 개별 조건의 T/F 실행          │
  │                       │                                        │
  │                       └── MC/DC: 각 조건의 독립적 영향 증명        │
  │                                                                  │
  │   ※ 상위 수준으로 갈수록 더 엄격한 검증                             │
  │   ※民航/원자력 등 안전 중요 시스템에서는 MC/DC 필수                │
  │                                                                  │
└─────────────────────────────────────────────────────────────────┘
  • 섹션 요약 비유: 결정 커버리지는 **'양자 골목 양쪽 길 검증'**과 같다. 골목에서 왼쪽 길과 오른쪽 길(두 branch)이 있을 때, 항상 왼쪽만 가면 오른쪽에何がある거나 위험이 있는지알 수 없다. 양쪽을 모두 걸어봐야 골목 전체를 安全に把握할 수 있다. 테스트도 마찬가지로 if-else의 양쪽分支 모두 테스트해야 전체를 검증한 것이다.

최신 동향

  1. CI/CD에서의 결정 커버리지 게이트: CI/CD 파이프라인에서 결정 커버리지 임계값을 설정하고, 미달 시 빌드를失敗시키는 정책 도입. Airbnb, Netflix 등 선도 기업에서採用
  2. 안전 중요 시스템 표준 강화: 자동차 functional安全(ISO 26262), 의료기기(IEC 62304) 등에서 안전 수준에 따라 결정 커버리지 또는 MC/DC 요구
  3. 커버리지 자동 분석 도구 발전: SonarQube, Codecov 등이 결정 커버리지를 포함한 다양한 커버리지 지표를 자동 분석하고可視化

한계점 및 보완

  • 복합 조건 내부 검증 불가: "A and B"에서 A가 false이면 B는 평가되지 않는데, 이러한 Short-circuit 동작의 세부 내용은 검증하지 않는다.
  • 100% 결정 커버리지도 보장할 수 없는 것: 모든 분기를 실행하더라도, 특정 값 조합에서 발생하는 오류는 발견되지 않을 수 있다.
  • 시간과 비용: 더 높은 커버리지를 달성하려면 더 많은 테스트 케이스와 시간이 필요하다.

결정 커버리지는 구문 커버리지보다 엄격한 테스트 충분성 지표로, 분기문의 모든 결과를 테스트하는지를 검증한다. 특히 안전 중요 시스템에서는 필수적인 커버리지 수준이며,_DO-178B/C와 같은 국제 표준에서 요구되고 있다. 그러나 결정 커버리지 100%도 모든 결함을 발견할 수 없으며, 프로젝트의要求사항에 따라 적절한 커버리지 수준을設定해야 한다.

  • 섹션 요약 비유: 결정 커버리지는 **'교차로 신호등 양방향 확인'**과 같다. 교차로의 신호등이 녹색이면 좌회전/직진/우회전(여러 branch)이 가능하지만, 녹색만 테스트하면 다른 색상(红/黄)일 때의 동작을알 수 없다. 모든 신호 색상(참/거짓)을 테스트해야 교차로 전체의 동작을 安全に把握할 수 있다. 테스트도 마찬가지로 분기의 모든 결과를 테스트해야 전체 시스템 동작을 검증한 것이다.

참고

  • 모든 약어는 반드시 전체 명칭과 함께 표기: API (Application Programming Interface)
  • 일어/중국어 절대 사용 금지 (한국어만 사용)
  • 각 섹션 끝에 📢 요약 비유 반드시 추가
  • ASCII 다이어그램의 세로선 │와 가로선 ─ 정렬 완벽하게
  • 한 파일당 최소 800자 이상의实质 내용