프로그램의 논리적인 복잡도를 정량적으로 측정하기 위해 제공되는 메트릭

Tom McCabe가 제안한 메트릭 (V(G)). 프로그램 제어 흐름 그래프의 독립적인 경로 수를 계산하여 복잡도와 최소 테스트 수를 동시에 도출한다.

계산 공식

플로우 그래프(Flow Graph)에서 다음 3가지 공식이 모두 동일한 값을 산출한다.

공식의미
V(G) = RR = 노드들로 둘러싸인 영역과 그래프 밖 영역의 수
V(G) = E - N + 2E = Edge(화살표) 수, N = Node 수
V(G) = P + 1P = Predicate(조건) 노드 수

예시

성적 관리 프로그램:

  • R = 3
  • E - N + 2 = 9 - 8 + 2 = 3
  • P + 1 = 2 + 1 = 3

→ V(G) = 3, 최소 3개 이상의 독립 경로를 테스트해야 전체 내부 구조를 커버.

조건 연산자 처리

하나의 if 조건 안에 &&·|| 단락 평가 연산자가 있으면 각 연산자마다 +1. 단락 평가가 추가 분기를 만들기 때문.

int aFunction() {          // 기본 1
    int A = 0;
    if (A && B) { /*...*/ } // if(+1) + &&(+1)
    if (C || D) { /*...*/ } // if(+1) + ||(+1)
    return 0;
}                          // V(G) = 5

SEI 신뢰성 위험도 기준

SEI(Software Engineering Institute)가 정의한 순환 복잡도 구간별 해석:

순환 복잡도신뢰성(Reliability) 위험도
1~4단순한 프로그램 / Little risk
5~10잘 구조화된 프로그램 / Little risk
11~20다소 복잡한 프로그램 / Moderate Risk
21~50매우 복잡한 프로그램 / High risk
> 50테스트 불가능한 프로그램 / VERY HIGH RISK

수정 시 추가 에러 발생 확률

기존 에러 수정 시 새 에러를 유입시킬 확률이 복잡도와 함께 급증:

순환 복잡도추가 에러 발생 확률
1~105%
20~3020%
50 이상40%
100 이상60%

→ 복잡도 50 이상 함수는 리팩토링 없이 수정하면 40% 확률로 회귀 결함을 낳는다.

기준치

표준/조직기준
JSF AV C++ Coding Standard20 이하
Microsoft15 = 리팩토링 한계치, 10 초과 시 리팩토링 고려
HIS Source Code Metrics (자동차)1-10
자동차 도메인10 이하 통과 / 10~30 조건부 통과 / 30 초과 반드시 수정

Basis Path Coverage와의 관계

화이트박스 테스팅경로 커버리지(Basis Path Coverage) 4단계 중 2단계가 순환 복잡도 계산이다.

  1. Flow Graph 작성
  2. 순환 복잡도 계산
  3. 독립 경로 정의 (V(G)개)
  4. 테스트 케이스 작성

→ V(G) = 테스트 케이스의 최소 수 (구조 커버리지 100% 보장).

같이 보기