Tutorials

팀 역량을 강화하는 상위 6가지 코드 품질 메트릭

Read this post in other languages:

완벽한 코드 품질은 대부분의 소프트웨어 개발자가 바라는 목표입니다. 하지만 그 의도는 간단할지라도 이를 현실화하기 위한 전략은 복잡할 수 있습니다. 품질을 측정하는 방법과 대상은 검토 프로세스의 결과를 개선하는 핵심 요소입니다.

지속적인 개선, 기술적 우수성에 대한 지속적인 관심, 정기적인 성찰의 원칙을 지키는 팀이라면 더욱 그러합니다. 소프트웨어 개발 분야에서 20년 이상의 경험을 보유한 JetBrains는 팀에 가장 효과적인 메트릭이 무엇인지 공유하기 위한 인사이트를 수집했습니다.

실용적인 코드 품질 메트릭과 그 측정 방법

1. 순환 복잡도(CYC)

CYC는 소스 코드의 독립적인 경로 수를 기반으로 프로그램 코드 흐름의 복잡성을 측정한 것입니다. 복잡성이 증가함에 따라 코드를 이해하고, 테스트하고, 유지 관리하기가 더욱 어려워지기 때문에 이는 중요한 메트릭입니다.  애자일 접근 방식을 따르고 있다면 지속 가능성과 유지 관리 가능성이 핵심입니다. CYC를 통해 단순화가 필요한 부분에 대한 단초를 얻을 수 있습니다.

간단한 예를 통해 이 메트릭이 어떻게 작동하는지 살펴보겠습니다. 어떠한 조건이나 브랜치 없이 구문을 순차적으로 실행하기만 하는 코드 조각을 생각해 보세요.

public int sum(int a, int b) {
   System.out.println("Adding two numbers: " + a + " + " + b);
   return a + b;
}

코드에 브랜치가 없기 때문에 매개변수 값을 조합하면 함수의 모든 구문이 실행됩니다. 따라서 이 코드의 CYC 결과는 1입니다.

입력을 확인하기 위한 조건문을 도입하면 코드에 단일 브랜치 대신 두 개의 가능한 실행 경로가 포함되므로 CYC가 두 배가 됩니다.

public int sum(int a, int b) {
   if(a < 0) throw new IllegalArgumentException("Parameter a should be positive");
   System.out.println("Adding two numbers: " + a + " + " + b);
   return a + b;
}

두 번째 매개변수를 테스트하기 위해 다른 조건을 추가하면 CYC 결과가 3으로 증가합니다.

public int sum(int a, int b) {
   if (a < 0) throw new IllegalArgumentException("Parameter a should be positive");
   if (b < 0) throw new IllegalArgumentException("Parameter b should be positive");
   System.out.println("Adding two numbers: " + a + " + " + b);
   return a + b;
}

모든 조건문이나 루프 블록은 메서드의 CYC 메트릭에 추가되므로 모든 코드 브랜치를 통해 실행하는 데 필요한 테스트 수에 기여합니다.

CYC 값이 높다고 해서 코드에 버그가 있거나 손상되었다는 의미는 아니지만 코드의 유지 관리가 어려워서 새로운 변경 사항으로 인해 쉽게 손상될 수 있다는 것은 확실합니다. IntelliJ IDEA는 에디터에서 바로 지나치게 복잡한 메서드를 알려줄 수 있습니다. Overly complex method(지나치게 복잡한 메서드) 검사에 대한 임곗값은 Settings(설정) | Editor(에디터) | Inspections(검사)에서 구성할 수 있습니다.

JetBrains Qodana를 사용한 중복 분석을 통해 중복 코드 찾기

기본적으로 임곗값은 10으로 설정됩니다. 그러나 이 메트릭을 2로 변경하면 에디터에서 아래의 예시 코드가 강조 표시됩니다.

정적 코드 분석의 예

전체 프로젝트에 대해 이 검사를 활성화하는 방법

서버 측 코드 분석에 Qodana를 사용하는 경우(로컬뿐만 아니라 전체 팀의 코드 품질 추적을 위해), CYC를 자동으로 검사할 수 있습니다. Recommended(권장) 프로파일을 선택하고 코딩 중인 언어에 대해 이 프로파일이 활성화되었는지 확인하세요.

JetBrains Qodana로 코드 복잡성 검사 활성화

결과 해석

Tom McCabe Jr.는 미국 국토안보부에서 발표한 ‘ Software Quality Metrics(위험 식별을 위한 소프트웨어 품질 메트릭)'[다운로드] 프레젠테이션에서 메서드의 CYC 메트릭 값이 10보다 작으면 코드가 충분히 단순한 것으로 간주된다고 말했습니다.

메트릭이 50을 넘으면 코드가 지나치게 복잡하고 테스트할 수 없는 것으로 간주됩니다. 그러나 실제로는 6 미만의 값을 목표로 삼고, 결과가 10을 초과하면 경고 수준으로 생각해야 합니다. 이는 복잡성이 더 이상 커지지 않도록 함수를 단순화해야 할 때임을 나타냅니다.

CYC 점수에 대한 권장 범위는 다음과 같습니다.

  • 1~5 – 단순한 코드이고 테스트 및 디버그가 용이함
  • 6~10 – 더 복잡하고 위험도가 보통임
  • 10~20 – 위험도 높고 주의해야 함
  • 20 이상 – 매우 복잡한 코드이며 이해하고 유지 관리하기가 어려움

2. 코드 중복 비율

코드 중복 비율은 코드 베이스의 여러 위치에 동일하거나 유사한 코드가 얼마나 많이 나타나는지 확인하는 데 도움을 줍니다. 코드 중복 수준이 높으면 유지 관리가 증가하고 버그 발생 가능성이 높아지며 코드 가독성이 저하될 수 있으므로 이는 중요한 메트릭입니다.

Qodana에서는 중복 검사가 기본적으로 활성화되어 있지만 IntelliJ IDEA 및 WebStorm, Rider 같은 다른 IDE에서 중복 탐지를 구성할 수도 있습니다.

Qodana 중복 비율 검사
Qodana를 이용한 중복 확인

결과 해석

이상적으로는 코드 중복 비율을 5% 미만으로 유지해야 합니다. 이렇게 하면 하나의 개선 사항이나 문제 해결을 위해 코드의 많은 부분을 변경하는 불필요한 리팩터링을 방지하는 데 도움이 됩니다. Qodana와 같은 도구를 사용하여 로컬 또는 서버 측에서 지속적으로 코드 중복을 모니터링하세요.

3. 코드(테스트) 커버리지

최대 커버리지로 테스트 케이스를 작성하면 수동 테스트 전에 소프트웨어가 예상대로 실행되는지 확인하는 데 도움이 될 수 있습니다. 더 효과적으로 테스트하면 고품질 제품을 더 빠르게 시장에 출시할 수 있습니다.

또한 높은 테스트 커버리지는 유지 관리성을 강화하고 중복 코드에 대한 경고를 제공할 수 있습니다. 커버리지가 높을수록 코드 결함이 줄어든다는 가정하에 측정되기 때문입니다.

코드 테스트 커버리지를 측정하는 가장 일반적인 방법은 코드 줄 수로 측정하는 것입니다.

코드 커버리지 비율 = (알고리즘으로 테스트된 코드 줄 수/시스템 구성 요소의 총 코드 줄 수) * 100

그러나 두 가지 다른 전략이 있습니다.
1) 구문으로 측정
2) 브랜치로 측정. 브랜치를 통한 측정은 순환 복잡도 메트릭과 함께 사용하면 더 효과적입니다. 복잡성은 코드를 처리하기 위해 얼마나 많은 테스트를 구현해야 하는지를 보여주기 때문입니다.

코드 커버리지 평가

JVM, JS 또는 PHP용 Qodana와 함께 Qodana Ultimate 또는 Ultimate Plus 라이선스가 있는 경우, qodana.recommended 또는 qodana.starter 프로파일에서 코드 커버리지 테스트를 실행할 수 있습니다. 여기에서 코드 커버리지 측정을 설정하는 방법에 대해 알아보세요.

JetBrains Qodana를 사용한 코드 커버리지 테스트

4. 가능한 버그 수

당연하게도 코드의 버그 수는 최대한 0에 가깝게 유지되는 것이 좋으며, 코드 분석을 통해 모든 종류의 버그를 표시할 수 있습니다. 연산을 객체가 필요한 곳에서 수행하려고 할 때 발생하는 NullPointerExceptions가 한 가지 예입니다. 이 예외는 런타임에 null인 객체 인스턴스의 메서드를 사용하거나 해당 인스턴스의 변수에 액세스하려고 할 때 나타나는 경우가 많습니다.

버그가 있는 제품 버전을 출시하지 않으려면 이러한 문제를 조기에 파악하는 것이 중요합니다. 특히 코드에서, 또는 동료 검토 과정에서조차 이러한 문제를 즉시 알아차리지 못할 수도 있기 때문입니다. Qodana는 사용 후 데이터베이스 연결이 안전하게 닫히지 않는 등 잘못된 리소스 처리와 관련된 문제를 쉽게 찾아낼 수 있습니다.

5. 코드 스멜

중단된 API 사용과 같은 코드 스멜의 측정은 소프트웨어 코드 베이스의 상태를 건전하게 유지하는 데 중요합니다. 중단된 API 사용을 수동으로 평가하여 검토자가 중단된 API를 식별하고 대안을 제시하도록 할 수 있지만 가장 일반적인 접근 방식은 Qodana와 같은 정적 코드 분석 도구를 사용하는 것입니다.

6. 취약점의 수

코드의 취약점은 보안 침해, 데이터 유출 또는 기타 보안 관련 문제로 이어질 수 있는 보안상의 약점이나 문제를 의미합니다.

취약점은 하나만 있더라도 심각한 보안 침해로 이어질 수 있습니다. 이는 Log4J 취약점의 영향을 크게 받은 X(이전 Twitter), CloudFlare, AWS의 예만 보더라도 알 수 있는 사실입니다. 이러한 취약점은 보안 취약점, 구성 오류, 액세스 제어 문제, 종속성 취약점 등과 같은 다양한 형태로 나타날 수 있습니다.

JetBrains Qodana Cloud 대시보드를 이용한 보안 취약점 확인

위에서 취약한 종속성에 플래그를 지정하는 Qodana Cloud의 검사를 볼 수 있습니다. Qodana 데이터로 종속성 라이선스를 확인할 수도 있습니다.

코드의 취약점 수를 파악한 후에는 그 중 어떤 것이 중대한 취약점이고 가장 큰 위험을 초래하는지 평가할 수 있습니다. 여기에서 우선순위가 가장 높은 문제에 대한 해결 조치를 즉시 시작하고 덜 중요한 문제는 Baseline에 저장하여 나중에 해결할 수 있습니다.

정적 코드 분석으로 코드 품질 측정 단순화

코드 품질 메트릭은 보다 효율적이고 유지 관리가 용이한 깔끔한 코드로 가는 길을 안내합니다. 이러한 메트릭은 시간 경과에 따른 프로젝트 상태를 전체적으로 보여주므로 제품 개선과 팀 협업 면에서 전략적인 이점을 누릴 수 있습니다.

이러한 메트릭을 전달 프로세스에 구현하려는 경우 Qodana가 도움이 됩니다. Qodana는 모든 CI/CD 워크플로에 완벽하게 통합되므로 전체 팀에게 코드 품질 정보의 단일 소스를 제공합니다. 무엇보다 검사 결과를 JetBrains IDE에서 즉시 확인할 수 있으므로 문제를 신속하게 해결할 수 있습니다.

지금 사용해 보고 가장 많이 사용하게 되는 메트릭이 무엇인지 알려주세요. Qodana를 시작하려면 아래 버튼을 클릭하세요. 또는 코드 품질을 측정하는 방법에 대해 자세히 알아보려면 문의해 주세요.

Qodana 무료로 사용해 보기!

게시물 원문 작성자

Jessie Cho

Anton Arhipov

Jessie Cho

Kerry Beetge

Qodana Advocate, Tech Journalist and IoT enthusiast.

image description