본문 바로가기
코드프레소 체험단/SW 품질 향상을 위한 코드 정적분석

[SW 품질 향상을 위한 코드 정적분석] 소프트웨어 품질과 코드 품질 지표

by 의정부핵꿀밤 2022. 4. 1.
728x90

<SW 품질의 개념>

 

소프트웨어 품질(Software Quality)

  • 정의
    • 소프트웨어가 지닌 바람직한 속성의 정도 [IEEE]
    • 요구되는 기능을 발휘할 수 있는 소프트웨어 특성의 정도 [DoD]
    • 소프트웨어가 기능, 성능 및 만족도에 있어서 명시된 요구사항 및 내재된 요구사항을 얼마나 충족하는 가를 나타내는 소프트웨어 특성의 총체 [Pressman]
  • 소프트웨어 품질의 구분
    • 제품(Product) 품질
      • 제품 자체가 가지는 품질
      • 완성된 소프트웨어가 운용될 환경에 올려져 최종 시스템이 완성되었을 때, 소비자가 요구하는 바에 얼마나 부합되는지를 나타내는 품질
    • 프로세스(Process) 품질
      • 소프트웨어를 개발하기 위해 필요한 모든 개발 활동이 계획을 준수하여 개발하였는가를 나타내는 품질
      • 그 활동이 효과적인지에 대해 검토(Review) 및 감사(Audit) 활동을 통해 확인

 

 

 

소프트웨어 제품 품질 보증

  • Verification (검증)
    • 제품이 올바르게 생성되고 있는가? = Are we building the product right?
    • 소프트웨어가 정확한 요구사항에 부합하여 구현되었음을 보장하는 활동
    • '요구사항 명세서에 맞게 올바른 방법으로 제품을 만들고 있음' 을 보장
  • Validation (확인)
    • 올바른 제품을 생성하고 있는가? =  Are we building the right product?
    • 소프트웨어가 고객이 의도한 요구사항에 따라 구현되었음을 보장하는 활동
    • '고객이 의도한 환경이나 사용 목적에 맞게 올바른 제품을 만들고 있음' 을 보장

 

 

 

 

Verification & Validation (테스트) 종류

  • 정적(Static)인 방법
    • 소프트웨어를 실행하지 않고 결함을 찾아내는 것
    • 여러 참여자들이 모여 소프트웨어를 검토하여 결함을 찾아내거나 정적 검증 도구 이용
    • 소프트웨어 개발 중에 생성되는 모든 산출물에 대해서 적용 가능
    • 대표적인 방법 :
      • 동료 검토(Peer Review) : 인스펙션(Inspection), 워크스루(Walk-through), 데스크체크(Desk Check)
      • 도구를 이용한 정적 분석 : 룰 기반 정적분석(PMD, BugFind 등)
  • 동적(Dynamic)인 방법
    • 소프트웨어를 실행하여 결함을 찾아냄
    • 발견된 결함은 디버깅 활동으로 확인하며 수정함
    • 대표적인 방법 : 
      • 명세기반/블랙박스 테스트
      • 구조기반/화이트박스 테스트

 

 

 

개발 단계별 주요 산출물과 테스트 기법

 

 

 

 

소프트웨어 제품 풀질 특성

  • 소프트웨어 제품 품질이 가져야하는 세부 속성

 

 

 

소프트웨어 제품 품질 특성 - 부특성

 


<코드 품질 지표 - 지표 정의와 규모>

 

소프트웨어 품질 지표

  • 정의
    • 사용 목적을 가지고 측정 및 분석하는 지표 중, 소프트웨어의 품질을 판단하는데 도움을 주는 지표
    • 활용하지 않을 지표라면, 측정하지 말아야 함
  • 측정 및 분석방법
    • 프로세스 및 계획에 따라 측정
    • 모든 지표는 정의되어야 함
      • 목적, 목표, 계산식, 측정 대상 및 방법, 측정 주기, 분석 및 해석 방법, 분석 주기

 

 

지표 정의 예제

 

 

 

 

규모 관련지표

  • 라인 수 (LOC : Line of Code)
    • 보통 공백을 제외한 라인 수를 의미한다
  • 주석 제외 라인 수
    • //, /**/ 등의 주석을 제외한 코드 라인을 의미한다 -> 순수 코드 라인
  • 주석 비율
    • LOC 중 코드 라인수의 비율
    • 전체 코드 중 주석이 얼마나 있는가?
    • 특정 도메인(임베디드 c)에서 주로 측정한다 -> 대략 20% 비율을 목표로 둔다
    • 웹 개발 같이 수정이 빈번하게 일어나는 경우에는 주석 비율이 낮은 게 좋다
  • 함수 라인 수
    • 함수 단위의 라인 수
    • 일반적으로 제한을 둔다

 

 

 

함수 라인 수

  • 함수 라인수가 길면 왜 나쁜가?
    • 소스코드 이해의 어려움
    • 의도하지 않은 실수를 할 수 있다
    • 테스트를 어렵게 한다
  • 기준은 얼마인가?
    • 일반 : 200
    • 기준 : 80
    • NASA : 60
    • VW : 50
    • 극한(XP) : 15

 

 

 

함수 라인 수를 줄이는 방법?

  • 다양한 리팩토링 방법이 존재한다
  • 리팩토링 : 함수의 입출력은 고정한 채 내부 로직을 개선하는 방법
  • 로직 자체의 개선
  • 추출

 


<코드 품질 지표 - 복잡도와 테스트 커버리지>

 

순환 복잡도 (Cyclomatic Complexity)

  • 함수의 제어 흐름이얼마나 복잡한지 측정
  • McCabe 순환 복잡도로 알려져 있다
  • 함수가얼마나 복잡한지 알려주는 지표
  • 계산 방법
    • Edge - Node + 2
    • 함수는 기본적으로 1의 순환 복잡도를 가짐
    • 분기문의 개별 조건 + 1
  • 기준
    • 일반적으로 10
    • 도메인, 개발 언어에 관계 없음
  • 순환 복잡도가 높으면?
    • 코드 이해의 어려움
    • 테스트의 어려움 일반적으로 순환 복잡도가 높을수록 결함 확률이 높다고 알려짐
    • 자동차 분야 기능 안전의 경우 낮은 순환 복잡도를 강력히 권고함

 

 

 

순환 복잡도를 줄이는 방법은?

  • 가장 단순한 방법은 추출
  • 보다 나은 방법은 함수를 잘 설계하는 것
    • 함수 접근 지정자 활용
    • 한 함수는 하나의 책임만 처리하도록 설계

 

 

 

테스트 커버리지

  • 의미
    • 테스트가 소스코드를 얼마나 실행했는가?
    • 주로 구조 기반(화이트박스) 테스트에서 측정
  • 종류
    • Statement : ';' 로 끝나는 문장 중 얼마나 테스트 했는가?
    • Branch : 각 조건문의 참/거짓을 얼마나 테스트 했는가?
    • MC/DC : 개별 조건식이 전체 조건식에 독립적으로 영향을 주는 상황을 얼마나 테스트했는가?
  • 측정 목표
    • 기능 안전 SW : 100%
    • 그 외 경우
      • 40~70% / MCDC는 측정하지 않음
  • 커버리지를 높이는데 도움이 되는 지표
    • 낮은 순환 복잡도
    • 짧은 함수

 


<코드 품질 지표 - 의존성 및 코드 중복>

 

의존성 지표

  • 함수 별 호출하는 건수
  • 함수 별 호출되는 건수
  • 변경 영향 비율(Stability)
    • 한 함수가 변경되면 코드의 몇 %에 영향을 미치는가?
  • 상호 참조
    • 상호 호출하는 파일이 있는가? - 변경에 대한 영향도 파악 목적
    • 목표 = 0

 

 

 

의존성 분석

  • 개요
    • 함수, 변수의 호출관계를 분석하는 것
    • 도구가 추구하는 방향에 따라 패키지/클래스(파일)/함수 단위로 표현
  • 목적
    • 아키텍처 구조에서 서브 시스템 간의 의존이 적절한지 확인
    • 서브 시스템 레이어에서 각 레이어 간 호출관계 (ex. Autosar)
    • 서브 시스템 레벨에서 각 레벨 간 호출관계 (자식과 부모 패키지)
    • 원형 의존성(상호 참조) 관계
    • 객체지향에 특화되어, 추상화와 구체화의 정도를 확인
  • 대표 도구

  • 의존성 분석 표현 종류
    • DSM : Dependency Structure Matrix로, X/Y축의 형태로 서브 시스템 간의 의존성 확인에 유리
    • 지표 : 호출 대상을 지표로 표현
    • 특히, 객체 지향 관련 도구는 Robert C. Martin이 논문을 근거로, 의존성 관련 지표를 정의하고 숫자로 표현
    • 다이어그램 : 호출 관계를 다이어그램으로 표현

 

 

 

Layered Architecture에서 서브 시스템 간 의존성

가급적 한 방향으로만 호출하는 것이 좋다!

  1. 각 레이어 간 호출 관계 (ex. Autosar)
  2. 동일 레벨 간 호출 관계 (자식과 부모 패키지)
  3. 원형 의존성(상호 참조) 관계

 

 

EX) DSM - Lattix

의존성 분석 도구

 

 

EX) 다이어그램 - Doxygen

  • 각 함수들을 기준으로 의존성을 보여준다
  • 함수를 선택하면 해당 함수를 기준으로 의존성을 정렬하여 보여준다

 

 

Robert C. Martin - OO Metrics

  • 기준은 패키지 단위
  • 객체 지향에 맞는 설계 지표
  • CC(Concrete Class) : 인터페이스나 추상 클래스가 아닌 구체 클래스의 수
  • AC(Abstract Class) : 추상 클래스나 인터페이스의 수를 나타내며 확장성의 척도
  • Ca(Afferent Couplings) : 나에게 의존하는 패키지의 수를 나타내며 독립성의 척도
  • Ce(Efferemt Couplings) : 내가 호출하는 패키지의 수를 나타내며 독립성의 척도
  • A(Abstractness) : A = AC / (CC+AC) 추상화 정도를 나타내며, 0은 구체적인 패키지이며, 1은 추상적인 패키지
  • I(Insability)
    • I = Ce / (Ce+Ca) 변화에 대한 안정성을 나타내며 0부터 1사이의 값
    • 0은 외부 변화에 영향 없는 패키지이며, 1은 작은 변화에도 영향 받는 패키지
  • D(Distance to Main Sequence)
    • Main Sequence로부터의 거리
    • Main Sequence란 이상적인 패키지로 완전 추상적이면서 안정적이거나 완전 구체적이면서 불안정한 패키지
  • Cycle(Package dependecy cycles) : 패키지들 상호 간에 의존성을 가지고 있을 때 발생

 

 

 

코드 중복

  • 코드 종복의 의미
    • 단순히 Copy-Paste 한 코드
    • Token 단위로 측정
    • 보통 100 Token 이상이면 중복으로 판정
  • 코드 중복은 왜 나쁜가?
    • 유지보수와 리팩토링을 어렵게 함
    • 결함을 복사함
  • 개선방법은?
    • 리팩터링 - 추출
    • 더 나은 설계 (공통 모듈)

 

728x90

댓글