본문 바로가기
IT일반/SW공학

[SW] NHN은 이렇게 한다! 소프트웨어 품질관리(2)

by 우공80 2023. 2. 18.
728x90

NHN은 이렇게 한다! 소프트웨어 품질관리
책이 많이 낡았어요

2023.02.17 - [IT 말고/책] - [SW][리뷰] NHN은 이렇게 한다! 소프트웨어 품질관리(1)

 

[SW][리뷰] NHN은 이렇게 한다! 소프트웨어 품질관리(1)

품질관리... 어떻게 하는 거지? 현재 진행하는 프로젝트가 중반에 접어들면서 현재의 품질 수준에 대한 점검이 화두로 떠올랐습니다. 단위테스트를 진행하기는 하지만, 단위테스트만으로는 부

woogong80.tistory.com

1부에서는 NHN의 QP(Quality Practice) 활동과 소프트웨어의 특징, 애자일 도입의 이유와 효과적인 명세 작성법, 단계적 빌드에 대해 알아보았습니다. 2부에서는 QP활동의 상세한 내용을 정리하였습니다. QP활동 자체에 대해 정리하였고, 세부적인 도구의 사용법등은 이미 책이 출간되고 10년이 넘게 지나서 현재와 맞지 않기에 제외하였습니다.

리뷰 2부 목차

01. 코딩 컨벤션
02. 효과적인 명세 작성
03. 단계적 빌드
04. 정적분석
05. 사이클로매틱복잡도
06. 중복코드분석
07.  QP의 현재와 미래

 

01. 코딩 컨벤션


코딩 컨벤션은 개발자 간 코딩 스타일을 일치시켜 코드의 가독성을 높이기 위한 표준 규약을 의미합니다. 변수나 함수의 네이밍 규칙이나 들여 쓰기 괄호 사용 등의 코딩스타일을 정의합니다. 보통 회사마다 코딩 컨벤션에 대한 가이드가 있습니다.

품질 지표 측정 항목 Red Yellow Green Gold
코딩 표준 준수율(%) A/B A. 도구에서 검사한 결과 에러가 없는 파일 수
B. 도구에서 검사한 파일 수
30% 미만 30%이상 70%미만 70%이상 90%미만 90%이상

위 표는 NHN의 코딩 컨벤션 준수율 측정기준입니다. 이때 단순한 에러수가 아닌 에러가 없는 파일의 비율로 코딩 표준 준수율을 산출했는데요. 일반적인 오류나 결함과 달리 코딩 컨벤션은 전체 파일에 모두 적용됐는지를 파악하는 것이 더 의미가 있다고 판단했기 때문이라고 합니다. 왜 더 의미가 있는지에 대한 설명이 없는데, 파일 기준으로 해야 하는 이유가 있는지 의문입니다. NHN에서 정한 코딩 표준 준수율 최소 수준은 30% 이상이라고 합니다. 아주 엄격하게 적용하지는 않은 것을 알 수 있습니다.

코딩 컨벤션 문서만 제공하고 개발자가 준수하기를 바란다면 실제 적용 효과를 거두기란 매우 어렵다. 또한 코딩 컨벤션을 정의한 문서는 분량도 매우 많아서 모두 기억하고 코딩에 적용하기는 쉽지 않다. 개발 일정이 촉박한 경우에는 코딩 컨벤션을 준수하지 않더라도 컴파일하는 데 아무런 영향이 없기 때문에 쉽게 지나칠 수 있다. 따라서 코딩 컨벤션을 준수하기 위해서는 도구의 도움이 필수적이다.

버그를 수정하거나 기능을 개선하기 위해 자신이 작성한 코드뿐 아니라 다른 개발자가 작성한 코드를 읽어야 할 때가 많다. 이때 개발자마다 코드 작성 스타일이 다르고 메서드명이나 변수명을 토대로 용도를 쉽게 파악하기 힘들다면 코드를 읽는 데 많은 비용이 소요된다. 따라서 NHN에서는 각 개발자가 일정한 형식에 따라 코드를 작성하도록 코딩 컨벤션을 정의했다.

코딩 컨벤션은 언어(자바, C/C++, 자바스크립트, 액션스크립트, 마크업) 별 네이밍 규칙, 코드 스타일, 주석, 보안 영역을 포괄한다. 여기엔 클래스나 메서드, 변수의 이름을 짓는 방법, 공백이나 줄 바꿈, 들여 쓰기의 정도, 파일, 클래스, 메서드, 상수 등의 주석 작성 방법, 주요 공격 유형별 방어 코드 작성 방법 등이 포함된다.

코딩 스타일을 점검하는 도구로는 코딩 컨벤션 위반 여부를 검사하는 도구와 포맷터가 있으며, 코딩 컨벤션 위반 검사 도구를 사용할 수 없는 경우에는 코드 리뷰나 조직에서 정한 방식으로 수동으로 검사할 수도 있다.

코딩 스타일 점검 도구는 코딩 컨벤션을 위반하는 코드를 자동으로 검출한다. 따라서 눈으로 일일이 코드를 보면서 코딩 컨벤션을 위반하는 코드를 찾지 않아도 되고, 코딩 컨벤션 문서의 내용을 모두 기억할 필요도 없다. 하지만 네이밍 규칙은 예외 사항이 많아 룰 구현에 한계가 있어 점검할 수 있는 항목이 적다. 따라서 도구를 사용하여 코딩 스타일을 점검한 다음에는 반드시 네이밍 규칙을 점검하는 코드 리뷰를 수행해야 한다

※ 참고: 코딩 컨벤션 위반 여부를 검사하는 도구는 Java용으로는 checkstyle, Eclipse Code style, jautodoc 등이 있습니다.

코딩 컨벤션에 대해 모르는 부분을 발췌해서 정리했습니다.
저도 코딩 컨벤션을 따르라고 개발자들에게 말을 하긴 하는데, 강하게 이야기하기에는 조금 애매합니다. 위 글에 나오는 것처럼 코딩 스타일이 조금 다르다고 오류가 생기는 것도 아니고요. 개발자가 많고, 인력교체가 잦아서 코드 보는데 어려움이 있다면 모를까, 고인 물들 위주로 돌아가는 저희 시스템에서는 그 고인 물들 편한 게 최고가 아닌가 싶습니다.

코딩 컨벤션 중에서도 네이밍규칙은 가독성을 높이기 위해 반드시 따라야 한다고 생각합니다. 저 스스로도 네이밍 대충 했다가, 제가 만든 코드를 제가 이해를 못 한 적이 종종 있습니다. 다른 사람이 작성한 코드는 말할 것도 없지요.
하지만, 네이밍 규칙도 경우에 따라 대체가 어려운 경우가 있습니다. 저희 legacy 시스템에는 DB테이블이나 변수명, 함수명에 한글발음 그대로 영문표기한 것이 있는데요. 회사 내에서만 쓰이는 비즈니스 용어라, 이걸 풀어쓰려면 풀어쓸 수 있지만, 풀어쓰면 아무도 이해하지 못할 것이기에 그대로 두는 경우입니다. 제 입장에서는 소스를 볼 때마다 눈에 거슬리는데, 대안이 없어서 참고 있습니다ㅋㅋ 예전에 읽은 개발자의 글쓰기에서도 비슷한 이야기가 있는데요. 가독성이 아무리 좋아도 다른 개발자가 이해 못 하면 소용없다는 것과 같은 맥락입니다.
예를 들자면, "콩나물 가격"을 저장하는 변수를 "kongnamulPrice"라고 네이밍을 하면 촌스럽기는 해도 누구나 이해하겠지만, "beanSproutsPrice"라고 지으면 개발자의 영어 수준에 따라 이해를 못 할 수 있습니다.

※ 참고: 코딩 컨벤션 위반 여부를 검사하는 도구는 Java용으로는 checkstyle, Eclipse Code style, jautodoc 등이 있습니다.

적용 결과 좋았던 점 적용할 때 어려웠던 점
- 코드 스타일이 통일되어 소스 코드 가독성 향상

- 소스 코드 가독성 향상으로 서스테이닝이나 코드리뷰에 도움이 됨

- 코딩 컨벤션에 대한 학습 효과가 있음
- 프로젝트별 특성에 따라 회사 전체 표준을 지키기 힘든 경우가 있고 기존 코드에 대해 소급적용하는 것은 부담이 큼

- 일부 개발 언어(Objective-C)는 자동 검사 도구가 지원되지 않아 표준 준수 여부 확인에 시간이 많이 소요됨

- 코딩 컨벤션이나 자동검사 도구가 빈번하게 업데이트되어 번거로운 점이 있음

- 준수율이 파일 단위로 측정되어 파일에 하나라도 준수하지 않은 사항이 있으면 준수율에 반영되지 않음

 

 

02. 코드리뷰

 

새로 작성하거나 수정된 코드를 어느 정도 리뷰했는지 코드 리뷰의 수행정도를 파악하기 위한 품질 지표로 코드 리뷰 수행률을 측정했다. 코드 리뷰 수행률은 새로 작성하거나 수정된 코드가 포함된 파일, 즉 변경된 파일 중 코드 리뷰를 수행한 파일이 몇 퍼센트인지 확인한다. 온라인 리뷰 협업 도구로 리뷰한 경우뿐만 아니라 오프라인으로 리뷰할 경우에도 형상 관리 시스템에 커밋할 때 커밋 코멘트에 리뷰를 수행했다는 의미로 [CR]을 입력하면 리뷰 협업 도구에서 자동으로 리뷰 수행률을 측정한다. 코드 리뷰 수행률을 측정해서 품질 측정 기준을 아래와 같이 Red, Yellow, Green, Gold 네 구간으로 나누었다.
품질 지표 측정 항목 Red Yellow Green Gold
코드 리뷰 수행율(%) A/B A. 코드 리뷰를 수행한 파일의 총 LOC
B. 변경된 파일의 총 LOC
30% 미만 30%이상 70%미만 70%이상 90%미만 90%이상
제한된 개발 일정에서 변경된 파일을 모두 리뷰하는 것은 불가능하다. 하지만 최소한의 주요 코드만이라도 30% 이상(Yellow 수준)은 리뷰하게 했으며 코드 리뷰 대상을 조직별로 정의하게 했다. 코드 리뷰 수행률이 30%에 못 미치는 경우 주요 코드가 리뷰됐는지, 테스트를 충분히 했는지를 확인했다. 주요 코드를 리뷰하게끔 코드 리뷰 수행률을 측정했으나 리뷰 수행률을 높이기 위해 형식적으로 리뷰가 수행된다는 부작용이 있어 2010년에는 필요에 따라 리
뷰를 자발적으로 하게 하고 리뷰 수행률은 측정하지 않고 있다.

코드리뷰는 당연히 해야 하는 것일까요? 개발 단계에서 품질을 높이기 위한 방법은 사실 몇 가지 없어서 코드리뷰를 포기하기는 힘듭니다. 하지만, 위에 굵게 표기한 것처럼 실제 도움이 안 되는 리뷰에 시간만 쓰고 있는 것이 아닌지 확인이 필요한 것 같습니다. 품질은 시간이 있어야 챙기게 됩니다. 일정에 쫓기는 개발자들은 강제하지 않으면, 코드리뷰를 패스할 가능성이 높고, 강제하면, 형식적으로 코드리뷰를 하게 됩니다. 

리뷰 수행 시점은 조직에 따라 형상 관리 시스템에 커밋하기 전이나 커밋한 후에 결정하며 신규/개편 개발 과제는 최소한 반복 개발 주기별로, 서스테이닝은 2주~1개월 간격으로 1시간씩 진행할 것을 권장한다.

리뷰는 코드 작성자와 리뷰어가 모여서 리뷰하는 오프라인 방식을 권장하며 온라인 협업 도구를 이용하는 것도 가능하다... (중략)

코드 리뷰 수행 절차 중 리뷰 대상을 선정하여 요청하고 결과를 취합하는 과정에서 가장 많은 비용이 드는데 이 과정을 온라인에서 일괄 처리해 주는 도구를 사용하면 많은 비용을 절감할 수 있다

온라인 코드 리뷰 협업 도구로는 Crucible을 도입했고 한 번 리뷰할 때마다 100~150 라인 정도를 리뷰했다. 또한 코드를 읽어가면서 개발된 코드가 작성자 의도대로 개발되었는지 리뷰를 수행하고 결과를 기록하게 했다. 하지만 리뷰를 제대로 수행했는지는 검증할 수 없고 단지 리뷰 결과에 대한 코멘트만 확인할 수 있으며 또한 Crucible의 성능 문제로 온라인으로 리뷰하는 데 어려움이 많았다.

2009년 7월부터 9월까지 수행한 리뷰 수행 결과를 분석해 보면 코멘트는 평균 1.6개로 코드 수정에 도움이 안 되는 코멘트가 많은 것으로 나타났다. 결과적으로 코드 리뷰가 효과적으로 수행되지 못한 것으로 판단되어 각 조직에서 필요한 경우에 한해 자율적으로 오프라인이나 온라인 코드 리뷰를 수행하게끔 지침을 바꾸고 강제적인 지표 수집 대상에서도 제외했다.

코드 리뷰에 있어 개발자들이 가장 어렵게 느끼는 점은 무엇을 검토해야 할지, 소스 코드를 어떻게 읽어야 할지 모른다는 것이다. 효과적인 리뷰 수행이 되도록 코드 읽는 방법에 대한 고도화가 필요한데 이 문제를 해결하기 위해 언어별로 코드 리뷰를 수행할 때 충점적으로 검토해야 하는 항목을 정의하고 있다.

예를 들면 다음과 같다.
- 중요한 기능만 리뷰, 정적 분석 결과 결함 검출 빈도가 높은 소스 코드만 리뷰, 조건문만 리뷰
- 버그나 장애 분석 결과 발생 빈도가 높은 소스 코드 오류 확인
- 가상의 코드를 입력하고 하나씩 따라가면서 제대로 동작하는지 확인

NHN가 코드 리뷰를 수행한 것을 보면 생각보다 많이 하지는 않았습니다.
제가 맡고 있는 프로젝트와 직접 비교는 어렵지만, 주기별로 1시간 진행해서 충분할까?라는 의문이 듭니다. 그리고 오프라인 리뷰가 효과적이긴 하겠지만, 시간을 더 많이 뺏긴다는 문제가 있을 것 같습니다. 제 생각에는 정기적으로 하기보다, 수시로 하되 온라인으로 코멘트를 남기는 식으로 하는 것이 요즘 트렌드에는 더 맞지 않나 생각이 들긴 합니다. 그리고 소스코드 상에 드러나지 않는 비즈니스 로직 같은 건 오프라인 리뷰를 하거나, 수시로 개발자들 간에 소통하면서 해결하면 되지 않을까요?

그리고 책에서는 모든 코드를 리뷰할 수 없다면 어떤 것을 리뷰해야 할지 기준점을 제시하고 있는데, 참고할만한 내용인 것 같습니다.

아래 표는 NHN의 코드리뷰 적용 결과입니다.

적용 결과 좋았던 점 적용할 때 문제점/어려웠던 점
- 좀 더 좋은 코드 작성 방법에 대해 공유하거나 코드 개선에 대한 의견 공유가 가능(학습 효과, 실력 향상)

- 코드를 작성할 때 좀 더 신중하게 되며, 로직상의 코딩 실수나 잘못된 코드 습관을 발견하여 고칠 수 있었음

- 프로젝트의 전체적인 내용 파악에 도움이 됨(전체 시스템 이해, 업무 이해도 향상)

- 인지하지 못한 오류를 QA단계 이전에 발견해 수정할 수 있음

- 기존에 비공식적으로 진행되던 팀 내 리뷰가 정형화되어 리뷰 수행에 도움이 됨

- 신입/신규 입사자, 주니어 개발자 코드에 대한 코칭 기회가 됨

- 로직 오류 수정에 도움이 됨
- 온라인 코드 리뷰 협업 도구인 Crucible을 권장 사용자보다 많이 사용하면 성능 문제로 리뷰 진행이 어려움

- 실제로는 오프라인 리뷰를 진행하고 리뷰 수행률을 측정하기 위해 온라인 코드 리뷰 협업 도구에 기록을 남겨야 함

- 리뷰를 수행하려면 별도의 리소스가 필요하며 서비스나 과제 이해도가 높아야 한다는 점이 어려움(이해가 부족한 상태에서 리뷰할 때는 비즈니스 로직 리뷰에 한계가 있음)

- 온라인 리뷰는 연관성을 고려하여 코드 리뷰를 수행하기가 어려움(오프라인 리뷰가 적합)

- 리뷰어 일정을 고려한 리뷰 요청이 어려움

- 프로젝트 기간 중 개발과 리뷰의 병행은 일정상 어려움이 있음

- 코드 리뷰 수행률 수치를 맞추기 위한 형식적인 리뷰 진행

 

03. 코드 커버리지


코트 커버리지는 새로 작성하거나 수정된 코드를 어느 정도 테스트했는지 개발자 테스트 수행 정도를 파악하기 위한 품질 지표입니다.

커버리지를 측정하지 않고 테스트를 수행할 때는 일반적으로 코드의 일부분만을 실행하는데 커버리지를 측정하면 테스트를 그만해야 하는지, 추가할 테스트는 없는지 확인할 수 있으며 개발자가 의무적으로 테스트를 수행하게 된다는 점에서 효과적이다. 코드 커버리지는 구문 커버리지의 경우 50% 이상, 브랜치 커버리지의 경우 40% 이상(Green 수준)을 권장하고, 이 수준에 못 미치면 테스트가 수행되지 않은 부분이 있는지, 추가할 테스트는 없는지 확인하여 테스트를 수행하게 했다. 특히 복잡도가 높으면서 테스트가 수행되지 않거나 미흡할 때는 충분히 테스트하게 했다.
품질 지표 측정 항목 Red Yellow Green Gold
코드커버리지-구문커버리지(%)
A/B*100
A. 테스트 수행된 구문수(개)
B. 구문  수(개)
30% 미만 30%이상 50%미만 50%이상 70%미만 70%이상
코드커버리지-브랜치 커버리지(%)
A/B*100
A. 테스트 수행된 브랜치 수(개)
B.브랜치 수(개)
20% 미만 20%이상 40%미만 40%이상 60%미만 60%이상

코드 커버리지에 가장 관심을 갖고 보았습니다. 최종 품질은 결국 테스트를 얼마나 열심히 했느냐에 달려있으니까요. 특히 제가 맡고 있는 프로젝트는 정확도가 생명입니다. 거의 정확도 99.999.....%를 달성하는 게 목표입니다. 높은 정확도를 목표로 하는 만큼 모든 개발 일정은 최대한 빨리 진행하고, 프로젝트 기간의 거의 절반을 테스트에 할애하는 계획을 세웠습니다. 프로젝트 마지막에 테스트 기간이 별도로 있지만, 그때 가서 조치하면 늦는다는 생각이죠. 

현재는 명세기반 테스트 케이스를 작성하고 있습니다. 그리고 최종적으로는 legacy 시스템과 대조를 통해 정합성 검증을 할 예정입니다. 아마 정확도 99%는 어렵지 않게 달성할 것이라고 생각하는데, 걱정되는 부분은 나머지 1%입니다. 기존에 한 번도 발생하지 않았던  케이스는 테스트가 되지 않을 가능성이 높으니까요. 

 코드 커버리지는 QP활동 중 가장 중요한 수행활동이지만, 적용할 때 반발이 심했다고 합니다. 하지만, 적용 후에는 개발자들이 가장 선호하고 효과적인 활동으로 꼽았다고 합니다.

코드 커버리지 측정은 도구 사용이 필수이며, covertura, clover, GCOV, BullseyeCoverage 등의 도구가 있습니다. 

코드 커버리지 측정도구는 코드를 분석하기 전에 소스 코드에 계측 코드를 삽입하고 컴파일하여 코드 커버리지를 측정합니다. 소스코드에서 테스트하지 않은 코드가 어디인지도 확인해 주며, 코드커버리지는 빌드마다 측정하여 누적 관리하게 됩니다.

적용 결과 좋았던 점 적용할 때 어려웠던 점
- 단위 테스트가 쉽도록 코드를 설계하고 개발함

- 단위 테스트를 작성하면서 기존 소스코드에서 리팩토링할 부분이 명확히 드러나고 좀 더 나은 설계를 할 수 있게 됨

- 서스테이닝을 할 때 오류 확인에 도움이 됨

- 소스 코드를 수정하고 나서 자체 검증에 수동 코드 작성없이 이전 테스트 코드를 재활용할 수 있어 편리함.

- 소스코드를 수정할 때 코드 정상 동작 여부나 부작용을 확인할 수 있음

- 비즈니스 로직 객체(Business Object)나 데이터 접근 객체( Data Access Object)에 대한 개별 검증 가능

- 실제 서비스에서는 드물게 발생하는 예외적인 케이스에 대한 테스트가 가능

- 전체 시스템이 구성되지 않은 상태에서도 테스트를 통한 기능 확인이 쉬움

- 기존 모듈을 수정할 때 회귀 테스트(Regression Test)로 오동작할 뻔한 경우를 막은 경우가 있음

- 테스트를 작성하는 과정에서 자연스럽게 코드 리뷰가 이루어지므로 완성된 코드를 다시 수정할 때 발생하는 버그 감소
- 테스트 코드 작성에 많은 시간이 소요되어 개발 일정에 무리가 있음

- 회사에서 요구하는 지표를 산출하는 데 커버리지 측정 도구를 수정해야 함

- 노하우와 지식 부족으로 다양한 경우( 예를 들면 Mock처리, DB관련, Action클래스, UI코드가많은 경우 등)에 대한 단위 테스트를 작성하기 어려움

- 소스 코드를 변경할 때 테스트 코드로 함께 변경해야 함

 

 

04. 정적분석

 

이때(코드리뷰를 할 때) 정적 분석 도구를 활용하면 추가 비용을 적게 들여서 미리 결함을 찾아낼 수 있다. 정적 분석( Static Analysis)이란 소프트트웨어를 실행하지 않고 도구를 이용해서 소스 코드나 바이너리를 분석해서 잠재적인 결함을 찾아내는 것을 말한다… (중략)

단, 도구를 지나치게 믿기보다는 보조수단으로 활용할 것을 권장한다. 코드 리뷰를 하기 전에 사용하여 코드의 품질을 검증하는 용도로 활용하면 더 효율적으로 리뷰를 진행할 수 있다.
품질 지표 측정 항목 Red Yellow Green Gold
잔존 정적 분석 결함 밀도(개/KLOC) 
A/B*1000
A. 가중치가부여된 정적분석 결함 수(개)
B. 전체 소스코드 라인 수(LOC)
6 이상 4이상 6미만 2이상 4미만 2미만

정적분석은 소프트웨어를 실행하지 않고 도구를 이용해서 소스코드나 바이너리를 분석해서 잠재적인 결함을 찾아내는 것을 말합니다. 테스트 전에 개발 품질을 확인할 수 있는 도구로 유용하게 사용할 수 있습니다. 하지만, 본문에서 나온 것과 같이 실제 결함이 아닌 경우가 있으므로 도구를 너무 믿기보다는 보조 수단으로 활용하는 게 좋습니다. 

정적분석 도구 CppCheck, FindBugs, 앤트, PMD 등이 있습니다. 

우리 회사는 결함의 등급을 나누고 높은 등급의 결함은 반드시 조치하라고 가이드하고 있는데, NHN은 잔존 정적 분석 결함밀도로 품질 수준을 체크하고 있는 것이 차이가 있었습니다.

많은 리소스를 투입하지 않고도 도구를 사용해 편리하게 결함을 검출할 수 있으므로 개발 조직에서 정적 분석 도구를 활발히 사용하고 있다. 하지만 결함을 검출하는 것에 비해 식별한 결함을 제거하기 위한 노력은 부진한 것으로 보인다.
NHN에서는 어떤 룰이 효과적인지 결정하기 위해 우선 심각도 수준이 높은 1~4 수준까지의 룰을 적용한 결과 언어별 발생 빈도가 높은 오류 유형을 분석하여 오류 수정 사례 가이드를 작성해 개발 조직에 배포했다. 아울러 동일한 결함이 재발하는 것을 방지하는 차원에서 개발자가 코드 작성 시점에 주의할 수 있게 꾸준히 가이드를 제공할 예정이며 적용 결과를 토대로 지속적으로 룰렛 조정 작업을 진행할 예정이다.

이 부분은 우리도 비슷합니다. 중요한 결함으로 분류된 것만 고치고, 단순한 권고 사항은 잘 안 지키려고 하시더라고요.

적용결과 좋았던 점 적용할 때 어려웠던 점
- 생각지 못한 NullPointerException 발생가능성을 사전에 방지

- 테스트할 때 발견하지 못한 에러를 찾아내서 수정함으로써 사전에 장애 방지

- QA에서발견하기 어려운 버그도 검출하여 수정 가능

- 결함 수정 과정에서 프로그래밍 언어에 대해 평소 간과했던 부분을 발견하게 되어 학습 효과가 있음

- 디버깅 도구(컴파일러)에서 검출하지 못한 오류 확인에 도움이 됨

- 코드 리뷰로 쉽게 식별이 되지 않는 잠재 오류를 찾아 수정할 수 있음
- 레거시 코드의 경우 코드 수정에 대한 위험부담이 큼

 

05. 사이클로매틱복잡도

복잡한 코드는 이해하기가 어려우므로 테스트하기 어렵고 결함 발생 가능성이 높으며 유지보수나 확장도 쉽지 않다. 즉, 품질 위험 요소가 높다고 할 수 있다.

코드가 복잡한 정도를 수치화하고 특정 기준 이상이면 조치를 취하면 복잡도를 제어할 수 있다. 예를 들면. if, else, switch 등의 조건문을 많이 포함하는 코드는 복잡한 코드에 해당한다. 복잡한 정도를 수치화하는 방법 중 대표적인 것으로 사이클로매틱 복잡도(cyclomatic complexity)가 있다. (이하 CC)

복잡도를 낮추는 방법은 여러 가지가 있다. 높은 복잡도를 가진 메서드를 여러 개의 메서드로 분리하거나 코드의 중복을 제거하거나, 또는 조건 연산을 분리하면 복잡도가 감소한다.

기기존의 레거시 코드까지 복잡도를 낮추기는 어렵겠지만 QP도입 이후 진행하는 신규/개편 개발이나 서스테이닝 개발에는 새로 작성하거나 수정한 코드에 대해서는 소스코드의 복잡도를 분석했다. 어떤 메서드가 복잡도가 높은지, 복잡도가 높은 메서드가 리팩토링이 필요한지를 확인했다. 만약 리팩토링을 할 수 없다면 복잡도가 높은 메서드를 대상으로 충분히 테스트가 이뤄졌는지 코드 커버리지를 확인했다.
품질 지표 측정 항목 Red Yellow Green Gold
CC가 30이상인 모듈 비율(%) A/B A. 도구에서 검사한 결과 CC가 30이상인 모듈 수
B. 도구에서 검사한 모듈 수
코드복잡도 미측정 또는 조직 목표 미달성 조직목표달성
(조직별로 목표 CC가 30이상인 모듈 비율 설정 전체)
0.5% 이하 0%

CC는 if, else, switch, for, while, try catch의 수를 세어 1을 더해주는 것이고, booleans 연산도 추가하면 CC2라고 합니다. (최솟값은 1)

책에서는 복잡도 측정 도구: N’SIQ collector를 소개하고 있는데, 네이버 개발자 센터 들어가 보니, 지원 종료로 나오네요. 한번 확인해 보고 싶었는데, 아쉽습니다. 다른 도구를 찾아봐야겠네요.

NHN의 경우 java로 개발하는 경우 프레임워크를 사용하므로 모듈이 정형화되어 복잡한 모듈이 거의 없었다고 합니다. 스프링 프레임워크를 쓰는 경우에는 복잡도가 낮다는 것으로 이해가 되기도 합니다.

복잡도가 높은 모듈은 무조건 리팩터링 해서 복잡도를 낮추게 하는 대신, 복잡도가 매우 높으면서 테스트는 거의 하지 않은 모듈이 없게 해서 품질에 대한 위험 부담을 줄이는 데 초점을 두었다. 복잡도가 높은 모듈은 반드시 검증하게 하고 사이클로매틱 복잡도는 유연하게 적용하길 권장하고 있다.

비즈니스 로직을 코딩하게 되면 if-else문이 필연적으로 늘어나기 마련이라 이런 부분을 고려해서 복잡도가 높다고 무조건 리팩토링을 하는 대신 테스트를 강화한 것이 아닐까 생각해 봅니다.

적용결과 좋았던 점 적용할 때 어려웠던 점
- 코드가 간결해져 가독성이 높아짐
- 복잡하지 않은 코드를 작성하려는 노력으로 복잡도 높은 코드가 감소함
- 코드 복잡도를 낮춘 결과 테스트 코드를 작성하기가 쉬워짐
- 복잡도 높은 코드를 분기해 코드 가독성이 높아짐
- 평소 메서드를 길게 작성하는 습관이 개선됨
- 코드 리팩토링 대상을 파악하는데 도움이 됨
- 레거시 코드의 복잡도를 낮추려면 코드의 리팩토링이 필요한데, 리팩토링하고 난 후 안정성에 대한 검증이 쉽지 않아 쉽게 수정하기 어려움

 

06. 중복코드분석

 

중복 코드는 개발자들이 가장 흔히 저지르는 실수 중 하나다. 코드를 중복해서 사용하면 코드를 읽기 힘들 뿐만 아니라 코드를 수정할 때 중복된 모든 부분을 수정해야 하므로 유지보수가 어려워진다. 중복 코드를 모두 수정하지 않아서 종종 장애가 발생하기도 한다. 따라서 중복 코드를 찾아서 제거하면 매우 효과적으로 유지보수 비용을 절감할 수 있으며 결함을 예방할 수 있다.

중복 코드를 제거하는 가장 좋은 방법은 리팩토링을 습관화하는 것이다. NHN에서 개발한다는 것은 동작하는 코드를 작성한다는 것만을 의미하지 않는다. 동작하는 코드를 만들고 동작 여부를 확인할 수 있게 테스트 코드를 작성하고 클린코드로 리팩터링 하는 모든 과정을 마쳐야 개발을 완료했다고 할 수 있다.

이를 위해서는 코드 작성, 테스트 코드 작성, 리팩토링 단계를 아주 작은 기능 단위로 반복해야 한다. 테스트 코드를 작성하거나 리팩토링을 조금이라도 미루면 자연스러운 개발 단계상의 작업이 아니라 부담스럽고 부수적인 작업이 된다. 리팩토링이 개발 단계의 자연스러운 일부분이 되면 동작하는 코드를 만들 때 기존의 코드를 복사해서 붙여 넣는 일을 반복하더라도 리팩토링 단계에서 바로 중복 코드를 제거할 수 있다. 하지만 습관적으로 리팩토링을 하게 되기까지는 오랜 시간이 걸린다.

중복코드가 버그를 만드는 최악의 습관이라고 합니다. 마침 오늘 소스를 살펴보는데, 거의.. 20개의 코드 중복이 있는 것을 발견했습니다. 중복이 있다 보니 길이도 너무 길고요. 혹시 수정할 일이 생기면 20개를 다 고쳐야 하니, 장애 발생 위험이 극히 높은 코드라는 생각이 들었습니다. 

이런 코드를 리팩터링 하라고 요청하는 것도 힘든 일입니다. 개발자 입장에서는 개발자가 아닌 사람이 코드를 지적하는 게 불편할 수도 있고요. 리팩토링을 몰아서 하지 말고 짧은 주기에서 하도록 요청을 해야겠습니다.

중복코드 분석도구로는 CPD (PMD)를 설명하고 있습니다. 다행히 아직 지원이 되는 도구인 것 같네요. 

07.  QP의 현재와 미래


NHN에서 적용한 5가지 QP활동(코딩 컨벤션, 코드리뷰, 코드 커버리지, 정적분석, 사이클로매틱 복잡도)에 대한 설문조사 결과 품질 향상에 효과적인 수행활동은 코드 커버리지이고, 그다음으로 정적분석과 코드 리뷰가 효과적이라고 응답했다고 합니다. 

다음 그래프는 QP활동 중 사전 학습이나 적용하는 데 드는 비용이 높다고 생각한 순서입니다. 코드 커버리지는 효과가 높으면서도 비용이 많이 드는 활동으로 나타났습니다. 

QP설문조사 2

다음으로 QP활동 중 앞으로 계속 유지되었으면 하는 하는 활동은 다음과 같이 나타났다고 합니다.

QP설문조사 3

약간의 차이가 있기는 하지만, 개발자들은 투입 비용(결국 소요 시간)과 상관없이 효과적인 품질 활동을 하기를 원하는 것을 알 수 있습니다. 

NHN은 QP를 적용하면서 처음에는 변화에 대한 저항이 있었으나, 실제 적용해 가면서 QP가 개발자가 수행해야 하는 기본적인 활동이고 품질 향상에 도움이 된다는 공감대도 형성되었다고 합니다. 그리고 다음과 같은 긍정적인 변화가 일어났다고 합니다.

- CI서버를 구축해서 지속적이고 자동화된 테스트 수행
- 코드 품질 수치화와 가시성 향상(구현 완료 시점에 개발 결과물의 품질을 정량적으로 확인)
- 품질에 대해 능동적으로 태도 변화 - 좋은 개발 습관으로 인한 품질 향상
- QA 업무와 역할 변화-QA가 구현이나 설계 단계에 적극적으로 관여

 

※ NHN테스트자동화 프레임워크인 NTAF에 대한 소개, 앤트, 허드슨, 테스트코드 작성팁이 있으나, 너무 오래된 자료라서 리뷰는 작성하지 않았습니다. NTAF는 네이버 개발자센터에서 더이상 지원되지 않으며, 허드슨은 젠킨스로 대체되었습니다. 

이 책을 읽고 나서

개발 조직 내에 품질 향상을 위한 활동을 도입하고자 한다면 개발자 스스로 적합하다고 느끼는 수행활동을 '지속 가능한 방법'으로 수행하고 이를 전파할 수 있는 조직 분위기를 마련해야 한다.

품질활동을 도입하여 적용할 때 흔히 개발 조직에서 대는 핑계는 촉박한 프로젝트 일정으로 적용할 여유가 없다는 것이다. 하지만 낮은 품질을 감수한다고 해서 프로젝트가 빨라지는 것도 아니고, 높은 품질을 요구한다고 해서 프로젝트가 느려지는 것도 아니다.
 개발자에게 프로젝트 일정을 준수하면서 요구되는 기능을 모두 구현하려면 어떤 부분이 바뀌어야 하는지, 어떤 부분이 문제가 되는지 물어본다. 그리고 문제를 어떻게 해결할 수 있을지 함께 고민해서 해결 방안을 마련해야 한다. 

단지 목표 수치를 맞추기 위한 또 하나의 부가적이고 형식적인 업무가 되지 않게 도입 초기부터 개발자, 관리자 모두 공감대를 형성하도록 노력해야 한다. 특히 효과적인 의사소통 채널을 구축하여 지속적이고 활발하게 의사소통할 수 있게 해서 오해가 발생하지 않도록 해야 한다. 

일 때문에 필요해서 읽었지만, 재미있었습니다. 특히 왜? 이런 활동들을 해야 하는지 문제인식 부분이 좋았습니다. IT에서는 자칫 왜? 에 대한 고민 없이 기술만 쫓는 경우가 많이 생기는데, 이런 왜 하는지 몰랐던.. 품질 활동에 대해 왜? 하는 지를 알 수 있어서 좋았습니다.

그리고 여러 가지 공감되는 내용들도 많고, 마냥 좋은 이야기만 적혀있는 것이 아니라 적용전이나 적용 후 어려웠던 점들까지 기술되어 있어서 참고가 될만했습니다.

한편으로는 이 책이 쓰인 게 이미 10년이 훌쩍 지났는데, 현재는 어떻게 하고 있을지 궁금합니다. 계속해서 같은 방식으로 품질관리를 하고 있을지, 아니면 또 다른 방향으로 개선이 되었을지.. 그리고 NHN이 10년 전에 하던걸 우리는 아직도 못한다는 것이.. 아쉽습니다. 

기존에 우리 조직도 애자일 프로세스를 도입하려고 했지만, 잘 안된 경험이 있습니다. 왜 애자일을 해야 하는지에 대한 공감대가 형성되지 않은 상태에서 Top-down으로 진행되었고, 애자일의 형식적인 부분만 차용하다 보니, 업무가 가중되기까지 했습니다. 거기에 애자일 프로세스를 도입하느냐 마느냐로 줄 세우기까지 했으니..

아무튼 이 책에 나와있는 기존의 문제들은 저희 조직도 크게 다르지 않아서, 이런 부분에 대해 공감대를 형성하고 점진적으로 개발 문화를 개선해 나갔으면 좋았겠다는 생각이 많이 들었습니다.

10년이 넘게 지나다 보니, 책에 소개된 도구들은 시간이 지나면서 없어지기도 하고, 새로운 도구로 대체되기도 해서, 내용 그대로 참고하기보다는 도구가 어떤 식으로 사용되는지를 파악하는 용도로 보면 충분할 것 같습니다.

저는 업무에 참고하기 위해 상세하게 정리했지만, IT 쪽에서 일하시는 분이라면 가볍게 읽어도 재미있게 보실 것 같습니다.

 

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

728x90

댓글