품질 메트릭 (Quality Metric)#
품질 메트릭은 소프트웨어 개발 프로세스, 제품, 테스트 활동의 품질과 효과성을 평가하고 측정하는 데 사용되는 정량적 지표이다. 이는 소프트웨어 품질의 다양한 측면을 수량화하여 개발 및 테스트 노력의 효율성, 신뢰성, 전반적인 성능에 대한 귀중한 통찰력을 제공한다.
크게 제품 품질과 프로세스 품질을 측정하는 두 가지 범주로 나눌 수 있다.
소프트웨어 품질 메트릭#
소프트웨어 품질 메트릭은 ISO/IEC 25010 소프트웨어 품질 모델을 기반으로 8가지 주요 품질 특성으로 분류할 수 있다.
기능적합성(Functional Suitability): 소프트웨어가 명시된 요구사항을 얼마나 잘 충족하는지를 측정한다.
- 기능 구현 완전성: (구현된 기능 수 / 요구된 기능 수) × 100%
- 기능 정확성: (정확히 동작하는 기능 수 / 전체 기능 수) × 100%
- 요구사항 충족도: (충족된 요구사항 수 / 전체 요구사항 수) × 100%
측정 방법: - 요구사항 추적 매트릭스(RTM)를 통한 요구사항 커버리지 분석
- 기능 테스트 결과 분석
- 사용자 수용 테스트(UAT) 결과 검토
성능 효율성(Performance Efficiency): 시스템의 성능과 자원 사용을 측정한다.
- 응답 시간: 사용자 요청에 대한 평균/최대 응답 시간(ms)
- 처리량: 단위 시간당 처리할 수 있는 트랜잭션 수(TPS)
- 자원 사용률: CPU, 메모리, 디스크 등의 사용률(%)
측정 방법: - APM(Application Performance Monitoring) 도구 사용
- 부하 테스트 도구(JMeter, K6) 활용
- 시스템 모니터링 도구를 통한 자원 사용률 측정
호환성(Compatibility)은 다른 시스템과의 상호 운용성을 평가한다.
- 데이터 교환 성공률: (성공한 데이터 교환 수 / 전체 시도 수) × 100%
- 프로토콜 준수율: (준수하는 표준 프로토콜 수 / 필요한 프로토콜 수) × 100%
- 통합 테스트 성공률: (성공한 통합 테스트 케이스 / 전체 테스트 케이스) × 100%
측정 방법: - API 테스트 도구를 통한 인터페이스 검증
- 통합 테스트 자동화 도구 활용
- 상호운용성 테스트 수행
사용성(Usability)은 사용자 경험의 품질을 측정한다.
- 사용자 만족도: 사용자 설문 조사 결과(5점 척도)
- 작업 완료율: (성공적으로 완료된 작업 수 / 전체 시도된 작업 수) × 100%
- 학습 용이성: 특정 작업 습득에 필요한 평균 시간
측정 방법: - 사용성 테스트 진행
- 사용자 피드백 수집 및 분석
- 행동 분석 도구를 통한 사용자 행동 패턴 분석
신뢰성(Reliability)은 시스템의 안정성을 측정한다.
- MTTF(Mean Time To Failure): 장애 발생 사이의 평균 시간
- MTTR(Mean Time To Recovery): 장애 복구까지의 평균 시간
- 가용성: (전체 운영 시간 - 장애 시간) / 전체 운영 시간 × 100%
측정 방법: - 시스템 로그 분석
- 모니터링 도구를 통한 장애 추적
- 카오스 엔지니어링 테스트 수행
보안성(Security)은 시스템의 보안 수준을 평가한다.
- 취약점 밀도: KLOC당 발견된 보안 취약점 수
- CVSS 점수: 취약점의 심각도 평가 점수(0-10점)
- 보안 패치 적용 시간: 취약점 발견부터 패치 적용까지 소요 시간
측정 방법: - 보안 취약점 스캐너 활용
- 침투 테스트 수행
- SAST/DAST 도구를 통한 보안 분석
유지보수성(Maintainability)은 코드의 유지보수 용이성을 측정한다.
- 순환복잡도: 코드의 분기점 수에 기반한 복잡도 측정
- 코드 중복률: 중복된 코드의 비율(%)
- 기술 부채 비율: 리팩토링이 필요한 코드의 비율(%)
- 주석 비율: 전체 코드 라인 대비 주석 라인 비율 (15-30% 권장)
- 코드 응집도: 모듈 내 기능들의 관련성 정도
- 코드 결합도: 모듈 간 상호 의존성 정도
측정 방법: - 정적 코드 분석 도구(SonarQube) 활용
- 코드 리뷰 결과 분석
- 기술 부채 추적 도구 사용
이식성(Portability)은 다른 환경으로의 이전 용이성을 측정한다.
- 환경 적응성: 지원 가능한 플랫폼 수
- 설치 용이성: 평균 설치 소요 시간
- 대체 용이성: 기존 시스템 대체에 필요한 노력
측정 방법: - 다양한 환경에서의 설치 테스트
- 컨테이너화 및 가상화 검증
- 마이그레이션 테스트 수행
프로세스 품질 메트릭#
개발 프로세스의 효율성과 효과성을 측정한다.
테스트 관련 메트릭:
- 테스트 커버리지: ‘테스트된 코드 라인 수 / 전체 코드 라인 수 × 100’
- 테스트 성공률: ‘성공한 테스트 케이스 수 / 전체 테스트 케이스 수 × 100’
- 테스트 자동화율: ‘자동화된 테스트 케이스 수 / 전체 테스트 케이스 수 × 100’
- 결함 발견율: 테스트 단계별 발견된 결함의 수
개발 생산성 메트릭:
- 리드 타임: 요구사항 접수부터 배포까지 소요되는 시간
- 코드 배포 빈도: 단위 기간당 배포 횟수
- 코드 변경 리드 타임: 코드 변경부터 배포까지 소요되는 시간
- 변경 실패율: ‘실패한 변경 수 / 전체 변경 시도 수 × 100’
주의사항#
이러한 메트릭들을 효과적으로 활용하기 위해서는 다음과 같은 프레임워크를 구축해야 한다:
측정 도구 인프라 구축
- 자동화된 측정 도구 설정
- 데이터 수집 파이프라인 구축
- 대시보드 및 보고서 시스템 구현
측정 프로세스 정의
- 측정 주기 및 책임자 지정
- 데이터 수집 및 검증 절차 수립
- 결과 분석 및 리포팅 프로세스 정의
기준값 및 목표값 설정
- 산업 표준 및 베스트 프랙티스 참조
- 조직의 현재 수준 분석
- 단계적 개선 목표 수립
지속적 모니터링 및 개선
- 정기적인 메트릭 리뷰 미팅
- 트렌드 분석 및 예측
- 개선 활동 계획 수립 및 실행
참고 및 출처#
코드 크기 메트릭(Lines of Code, LOC) 이 메트릭은 프로그램의 크기를 코드 라인 수로 표현하며, 소프트웨어 개발 프로젝트의 규모 추정, 생산성 측정, 품질 관리 등에 활용된다.
코드 크기는 다양한 방식으로 측정될 수 있으며, 각각의 측정 방식은 서로 다른 목적과 의미를 가진다.
특징과 기능 프로젝트 규모 추정: LOC는 소프트웨어 프로젝트의 크기를 추정하는 데 사용된다. 생산성 측정: 개발자나 팀의 생산성을 LOC를 기준으로 평가할 수 있다. 비용 산정: LOC를 기반으로 프로젝트 비용과 개발 노력을 추정할 수 있다. 복잡성 지표: 코드의 양이 많을수록 일반적으로 복잡성이 높아진다. 유형 물리적 코드 라인(Physical Lines of Code, LOC):
이는 가장 단순한 형태의 측정 방식으로, 파일의 전체 라인 수를 세는 것이다.
다음은 물리적 코드 라인의 예시입니다:
...
유지보수성 지수 (Maintainability Index) 유지보수성 지수는 코드를 얼마나 쉽게 유지보수할 수 있는지를 나타내는 0에서 100 사이의 수치이다.
이 지수가 높을수록 코드의 유지보수가 더 쉽다는 것을 의미한다.
유지보수성 지수의 계산 유지보수성 지수는 다음과 같은 요소들을 고려하여 계산된다:
Halstead Volume (HV): 코드의 복잡도를 수학적으로 계산한 값 Cyclomatic Complexity (CC): 코드의 논리적 복잡도 Lines of Code (LOC): 코드의 총 라인 수 주석 비율 (선택적) 기본적인 계산 공식은 다음과 같다:
$$ MI = MAX(0, (171 - 5.2 * ln(HV) - 0.23 * CC - 16.2 * ln(LOC)) * 100 / 171) $$
...
응집도(Cohesion) 응집도는 하나의 모듈이 얼마나 단일한 목적에 집중되어 있는지를 나타낸다.
모듈 내부의 요소들이 서로 얼마나 밀접하게 관련되어 있는지를 측정하는 척도이다.
높은 응집도는 모듈이 하나의 명확한 책임을 가지고 있음을 의미하며, 이는 좋은 설계의 특징이다.
특징 및 기능 모듈의 독립성을 나타냄 유지보수성과 재사용성 향상에 기여 모듈의 품질을 평가하는 지표로 사용 응집도의 종류 낮은 응집도부터 높은 응집도 순
우연적 응집도(Coincidental Cohesion):
서로 관련 없는 기능들이 한 모듈에 모여있는 경우.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // 우연적 응집도의 예 class Utility { public void calculateTax() { } public void formatDate() { } public void validateEmail() { } public void connectToDatabase() { } } // 개선된 버전 - 각 책임을 분리 class TaxCalculator { public void calculateTax() { } } class DateFormatter { public void formatDate() { } } class EmailValidator { public void validateEmail() { } } 논리적 응집도(Logical Cohesion):
논리적으로 비슷한 기능을 수행하지만 실제로는 다른 작업들을 하나의 모듈에서 처리하는 경우.
...
코드 중복도 (Code Duplication) 코드 중복도는 소프트웨어 내에서 동일하거나 유사한 코드가 반복되는 정도를 나타낸다.
중복된 코드는 유지보수를 어렵게 만들고, 버그 수정 시 여러 곳을 동시에 수정해야 하는 문제를 야기한다.
이는 일반적으로 바람직하지 않은 프로그래밍 관행으로 간주되며, 소프트웨어의 유지보수성과 확장성을 저해할 수 있다.
특징과 특성 유지보수 어려움: 중복된 코드는 변경 시 여러 곳을 동시에 수정해야 하므로 유지보수가 어려워진다. 버그 발생 가능성 증가: 한 곳의 수정을 다른 곳에 반영하지 않을 경우, 일관성이 깨지고 버그가 발생할 수 있다. 코드량 증가: 중복 코드는 전체 코드의 양을 증가시켜 가독성을 떨어뜨리고 디버깅을 어렵게 만든다. OCP(Open-Closed Principle) 위배: 중복 코드는 수정에 닫혀 있어야 한다는 SOLID 원칙에 위배된다. 중복 코드 감지 방법 수동 코드 리뷰: 개발팀이 협력하여 코드를 검토하고 중복을 식별한다. 코드 분석 도구 사용: SonarQube, PMD, ESLint 등의 도구를 활용하여 자동으로 중복 코드를 탐지한다. 버전 관리 시스템 활용: Git 등의 버전 관리 시스템을 통해 코드 변경 사항을 비교하여 중복을 식별한다. IDE 기능 활용: 대부분의 현대적인 IDE는 코드 중복을 찾는 기능을 내장하고 있다. 코드 중복의 유형 완전 중복(Exact Duplication):
동일한 코드가 그대로 복사되어 사용되는 경우.
...
결합도 (Coupling) 결합도는 서로 다른 모듈 간의 상호 의존성이나 연관성을 측정하는 지표이다.
낮은 결합도는 모듈이 독립적이며 변경 시 다른 모듈에 미치는 영향이 적음을 의미한다.
모듈이란 클래스, 컴포넌트, 패키지 등 코드의 논리적 단위를 의미한다.
특징 및 기능 모듈 간 상호작용 정도를 나타냄 소프트웨어 구조의 품질을 평가하는 지표로 사용 유지보수성, 재사용성, 테스트 용이성에 영향을 미침 결합도의 종류 낮은 결합도부터 높은 결합도 순
내용 결합도(Content Coupling):
가장 강한 형태의 결합도로, 한 모듈이 다른 모듈의 내부 동작에 직접 관여하는 경우이다.
...
테스트 커버리지 (Test Coverage) 테스트 커버리지는 테스트 대상 시스템이나 소프트웨어에 대해 얼마나 충분한 테스트가 수행되었는지를 나타내는 척도. 즉, 작성된 테스트 코드가 실제 프로덕션 코드를 얼마나 검증하고 있는지를 백분율로 표현한다.
테스트 커버리지를 측정하기 위해서는 실제로 코드가 실행되어야 하므로 테스트 커버리지는 기본적으로 동적 테스팅에 해당한다.
그리고, 테스트 커버리지를 측정하기 위해서는 코드의 내부 구조를 알아야 한다.
예를 들어:
구문 커버리지를 측정하려면 어떤 코드 라인이 실행되었는지 알아야 한다. 분기 커버리지를 측정하려면 조건문의 각 분기가 실행되었는지 알아야 한다. 경로 커버리지를 측정하려면 코드의 모든 가능한 실행 경로를 알아야 한다.
이러한 특성 때문에 테스트 커버리지는 화이트박스 테스팅 기법으로 분류된다. 테스트 커버리지가 실제 코드 실행을 통해(동적) 코드의 내부 구조를 분석하여(화이트박스) 테스트의 완성도를 측정하는 도구이다.
테스트 커버리지 자체는 측정 도구이며, 이를 측정하는 과정에서 정적 분석 도구를 보조적으로 사용할 수 있다.
...
Halstead Complexity Halstead 복잡도는 1977년 Maurice Howard Halstead가 제안한 소프트웨어 메트릭으로, 프로그램의 복잡성을 연산자(operators)와 피연산자(operands)의 수를 기반으로 측정한다.
이는 프로그램의 구현 난이도와 이해도를 정량적으로 평가하는 방법을 제공한다.
코드의 구현을 반영하지만 특정 플랫폼에서의 실행과는 독립적이다.
기본 측정 요소:
프로그램의 기본 요소는 다음과 같이 정의된다:
n1: 고유 연산자의 수 n2: 고유 피연산자의 수 N1: 총 연산자의 출현 횟수 N2: 총 피연산자의 출현 횟수
예를 들어, 다음 코드를 살펴보자. 1 sum = a + b * 2; 이 코드에서:
...
순환 복잡도 (Cyclomatic Complexity) 순환 복잡도는 1976년 Thomas McCabe가 제안한 메트릭으로, 프로그램의 논리적 복잡성을 정량적으로 측정하는 지표이다.
코드 내의 독립적인 경로의 수를 측정하여, 해당 코드를 완전히 테스트하기 위해 필요한 최소한의 테스트 케이스 수를 나타낸다.
순환 복잡도의 계산 방법은 다음과 같다:
V(G) = E - N + 2P
여기서:
E는 제어 흐름 그래프의 엣지(연결선) 수 N은 노드(구문) 수 P는 연결된 컴포넌트 수(일반적으로 1) 또는 더 간단하게:
V(G) = 분기문의 수 + 1
여기서 분기문은 if, while, for, case 등의 조건문을 의미한다.
...