순환 복잡도 계산기 쉽게 이해하기 — 개념과 원리
토머스 맥케이브가 제안한 순환 복잡도는 코드 조각을 지나는 독립 경로의 수를 셉니다. 함수가 얼마나 테스트하고 유지하기 어려운지 판단하는 데 쓰입니다. 이 계산기는 제어 흐름 그래프의 간선, 노드, 연결 요소로 구하거나 이진 분기 수로 구하고, 맥케이브가 제안한 한도 10과 비교합니다.
계산 방법
그래프로: M = E − N + 2P
분기 수로: M = 이진 분기 수 + 1
- E는 간선(블록 사이 가능한 이동), N은 노드(코드 블록), P는 연결 요소(함께 분석하는 별도 루틴) 수입니다.
- M은 기본 경로 집합의 테스트 경로 수이기도 합니다.
- 분기 지점 수 = M − P입니다.
원리
코드를 그래프로 그리면 분기 없는 블록이 노드, 가능한 제어 이동이 간선입니다. 분기가 없는 루틴은 경로가 하나라 M = 1입니다. if나 반복 조건 같은 양방향 분기는 독립 경로를 하나씩 더하므로 분기 수 + 1이 같은 값을 줍니다. 그래프 공식은 그래프 이론에서 나왔으며, 출구를 입구로 다시 이었을 때의 독립 순환 수를 셉니다. 구조적 테스트에서 M은 모든 독립 경로를 한 번 이상 지나기 위한 최소 테스트 케이스 수입니다.
예제 풀이
기본값인 간선 12, 노드 10, 루틴 1개로 계산합니다.
- M = 12 − 10 + 2 × 1 = 4입니다.
- 테스트할 기본 경로 = 4개입니다.
- 분기 지점 = 4 − 1 = 3개입니다.
- 4는 10 이하이므로 한도 이내입니다.
결과 해석
맥케이브는 모듈당 10 이하를 제안했고, NIST 구조적 테스트 보고서는 이 한도를 다루며 일부 조직은 근거가 있으면 조금 더 높은 값을 허용한다고 설명합니다. 한도를 넘는 함수는 작은 함수로 나눌 후보입니다. 복잡도가 낮다고 좋은 코드가 보장되지는 않고, 단순한 분기 처리에서는 높은 값도 괜찮을 수 있지만, 검토할 곳을 알려 주는 유용한 신호입니다.
흔한 실수
- 다중 switch를 분기 하나로 세는 경우(case마다 경로가 늘어납니다)
- 복합 조건을 잊는 경우(엄격하게 세면 "a && b"는 분기 두 개)
- M을 코드 품질의 직접 척도로 여기는 경우
- 노드(블록)와 개별 문장을 혼동하는 경우
자주 묻는 질문
좋은 순환 복잡도는 얼마인가요?
맥케이브는 함수당 10 이하를 제안했으며, 낮을수록 대체로 테스트하기 쉽습니다.
반복문도 복잡도를 높이나요?
네. 반복 조건이 분기라서 경로가 하나 늘어납니다.
복잡도를 줄이려면?
함수를 나누고, 중복 조건을 없애고, 조회 표를 쓰는 방법이 도움이 됩니다.
테스트와는 어떤 관계인가요?
M은 기본 경로를 모두 지나기 위해 필요한 최소 테스트 경로 수입니다. M이 4라면 서로 독립인 경로를 적어도 4개 시험해야 합니다.
도구마다 값이 다른 이유는?
불리언 연산자, 예외 처리, switch 문을 세는 방식이 도구마다 조금씩 다르기 때문입니다.
출처: A. H. Watson and T. J. McCabe, "Structured Testing: A Testing Methodology Using the Cyclomatic Complexity Metric", NIST Special Publication 500-235 (1996)