소스코드 리뷰에 대한 짧은 이야기

신현묵·2019년 12월 24일
20

소스코드 리뷰에 대한 개발자들의 생각과 시야

개발자와 개발 조직에게 소스코드 리뷰는 필수이며 운명이다.

팀간의 협업, 팀 내부의 대화를 보다 원활하게 만들어 주는 매우 필요한 절차로 꼭 필요하다. 향후 슬랙, 지라등의 협업도구가 명쾌하게 의미 있게 활용되려면 개발팀 간의 소스코드 리뷰는 필수적으로 수행되는 것이 좋다. 개발자의 작업내용에 대해서 서로 이해의 폭을 넓히고, 각자 개별 코드 작성의 기준에 대한 이야기를 취하는 개발 문화를 갖추어 가는데 매우 의미있기 행위이기 때문이다.

매우 당연한 이야기이지만, 소스코드 리뷰는 거북하고 불편하고 어렵고 힘들다. 아직도 개발자들에게 자신이 만든 소스를 완성하기 전의 상태이거나, 완성된 이후에도 코드리뷰를 한다는 것을 불편해 하는 개발자들이 많이 있다.

하지만, 그럼에도 불구하고 필수적인 개발문화의 하나가 되어야 하는 이유는 너무도 많다.

개발문화의 시작은 소통이고, 개발자들 간의 소통은 역시 코드에서 시작되어야 한다.

하나의 코드를 만들고, 하나의 코드를 서로 리뷰하며, 자신의 코드와 팀의 코드를 하나로 만들어 가는 행위는 개발문화에 너무도 중요한 기반에 해당된다.

초기에 코드리뷰 문화가 없을때에 팀 리더나 선배 개발자가, 동료 개발자들에게 코드리뷰에 대한 이슈를 설득하고 실제 행위를 발생시키는 것, 역시 매우 어려운일이다.

개발문화가 형성되어 있지 않은 상태에서, 별생각없다가 뜬금없이 코드리뷰 이야기를 회사나 팀리더에게서 갑자기 듣는 개발자는 매우 불편해 할 수 있다.

일반적인 개발자의 그러한 반응은 매우 당연한 반응이라고 생각하는 것이 좋다. 그러므로, 팀리더는 가능한 팀 세팅 초기 시부터 이 소스코드 리뷰 문화는 만들어질 수 있게 노력하는 것이 중요한 일이다.

초기에 세팅된다면 그 후에 들어오는 팀원들은 자연스럽게 그 문화에 익숙해진다. 이런 일련의 작업들은 결국 조직과 팀의 단결과 협력, 향후 유지보수에 매우 긍정적인 효과를 준다.

매우 당연하지만 개발자들은 팀에 소속되고 빠져나가기를 반복한다. 이를 두렵지 않는 팀으로 만드는 행위가 바로 코드 리뷰라는 행위이다.

인수인계와 유지보수를 위해서 소스코드 리뷰를 각 단계별에 배치해두고, 그 시간을 투자하는 것을 아까워하지 않도록 하자. 결국, 팀을 강하게 하고, 회사의 개발문화는 강해진다.

그렇다면, 소프트웨어의 본체인 소스코드를 타인이 리뷰한다는 것이 왜 어려울까? 그것에 대해서 한번 생각해보자.

그것은 소스코드는 언제나 완성상태가 아니라는 점 때문이다. 개발자의 생각은 무언가 다양한 변화를 예측하고 있고, 그 상세한 준비를 담고 있다. 언제나 소스코드는 완성 상태가 아니라, 변화되어야 하는 시간의 축을 담고 있기 때문이다.

그래서, 배포 권한을 개발자에게 부여하고, 매우 빠른 기획부터 배포까지 이루어지는 소프트웨어 품질을 컨트롤하는 속도가 빨라진 현재의 시점에서 본다면, 코드 리뷰라는 행위는 정말 필수 불가결한 행위에 해당한다.

이러한 필수적인 코드리뷰의 그 형태와 범위에 대해서 팀 내부에 정말 잘 정의되어야 한다. ( 팀리더가 아니라면, 팀내부에 이 행위를 강조하자. )

그래서, 보통 이 코드리뷰를 어떻게 할 것인가에 대해서 조직이나 담당하는 사람의 경우에는 명쾌한 판단 기준이 있어야 한다. 그러한 ‘판단기준’을 가져야만 명확한 리뷰될 수 있다.

이를 두고, 디자이너에게는 크리틱(critique-비평)이 있고, 개발자에게는 코드리뷰가 있다고 정의한다.

좋은 비평을 받고 좋은 리뷰를 하려면 다음의 3가지 원칙이 필수이다.

  1. 리뷰는 언제나 상호 합의가 되어진 상황에서 진행되어야 한다.
  2. 리뷰어의 해당 결과물에 대해서 객관성을 가지고 서로 인지해야 한다
  3. 개발자 자신의 작업물에 대해서 정말 객관적으로 바라볼 수 있는 작성가가 선정되어야 한다.

특히, 소프트웨어 코드는 정량적인 검토와 정성적인 검토를 구분해야 한다. 이 영역의 구분이 모호해지면, 리뷰는 그 방향성을 상실하게 된다. 그중에 특히, 정량적인 검토와 기본적인 규칙들은 가능한 자동화하고, 소스 형상관리 도구에서 기본적인 것들의 규칙들을 지키도록 권장하여야 한다. 최소한 이 정량적인 것만 자동화하고 규칙화해도 소프트웨어의 품질은 급상승한다.

하지만, 코드는 논쟁을 발생시키고, 어떤 것이 우선적인지에 대해서 서술하기 매우 어렵다. 이러한 점은 정성적인 부분에 대해서 검토할 때에 고민하자.

코드리뷰의 깊이나 관계는 어느 정도 해주어야 하는가?

현재시대 개발 방법론의 최신 추세는 ‘테스팅’을 주로 한다. SRS와 같은 요구사항에 집중하기 보다는, TDD와 같은 방법으로 완성 산출물을 높이는 방법을 현재에는 주로 사용하고 있다.

고속 개발과 빠른 배포, 짧은 개발 기간의 품질을 컨트롤 하는 가장 좋은 방법은 '테스트'를 자주, 많이, 전문적으로 하는 것이다.

과거의 개발방법에서는 비즈니스 속도가 느리고, 한번 개발되는데 6개월 이상의 시간이 소요되는 경우가 많았으며, 잘 정의된 요구사항을 통해서 결과물이 완성되는 SI성 개발이 주로였다. 그래서, 요구사항을 잘 정의하고, 아키텍처를 잘 정의하는 아키텍처링 과정을 가장 중요하게 여겼으며, 개발단계 전 단계에 더 많은 시간을 소요했다.

하지만, 앱서비스나 혁신적인 사업모델, 기존에 존재하지 않았던 마켓 정의, 기술적인 구분이 모호한 상태에서 이루어지는 환경에서는 요구사항의 정의를 명쾌하게 하는 것은 거의 불가능한 상황이다.

그래서, 기존의 개발방법론들은 현재의 개발스타일과 잘 맞지 않는다.

현재의 개발방법론으로는 사용자 요구사항은 계속 변화하는 것이 기본이며, 비즈니스를 정의하지 않은 상태에서도 개발이 진행되어야 하며, 단기적인 서비스의 행위에 대한 버그를 추적하는 결과물이 중요시되는 서비스의 시대이기 때문이다.

그래서, 슬프지만, 당장의 성과물을 위해서라면 코드리뷰보다는 테스팅에 집중하는 것이 더 효율적이다. 빠르게 고속 개발하고 테스트를 통해서 버그를 찾은 다음 수정하는 것이 ‘특정 기능들을 나열하고 기능을 만족하는 소프트웨어’의 경우에는 테스트 주도 개발 방법이 가장 적합하다고 할 수 있다.

하지만, 그럼에도 불구하고. 이러한 방향성이나 전체적인 틀에 대해서는 아키텍트가 아키텍처를 구체적으로 잘 결정하여야 한다. 현재의 팀구성이나 개발방법에서는 전체적인 아키텍처를 유지하는 다양한 기법이나 프레임워크들을 손쉽게 선택할 수 있기 때문이다. 정말 아키텍팅을 하기 좋은 시대인것은 맞다.

그래서 개발자들은 자기가 속한 개발 결과물이 어떤 프레임워크의 결과물이냐에 따라서, 프레임웍, 개발언어등이 매우 혼용되어져서 사용된다.

언어나 개발자들의 유입과 변경이 급변한다면, Reat방식의 API기반의 MSA가 적당하고, 성능이나 팀 구성, 언어의 정의나 특정 언어 개발자 수급이 효과적이라는 gRPC방식도 매우 유용한다.

어떤 방법이든지, 유연하게 구성이 가능한 시대가 된것은 맞다.

다만, 이번 글의 주목적은 코드리뷰. SRS중심이건, TDD중심이건. 코드리뷰는 중요하다는 것을 강조하고 싶다. 특히, 코드리뷰는 ‘기능 나열’이 아닌, 어느 정도 이상의 복잡도나 코드 품질이 필요한 경우에는 필수적으로 수행하는 것이 매우 현명한 행동이다.

물론, 코드리뷰 행위가 불필요한 업무들도 많다. 정해져 있는 단순한 업무를 수행하는 경우에는 굳이 할 필요 없다. 국내에서 SI를 하는 경우에는 대부분 코드리뷰가 필요 없는 업무를 하는 소프트웨어 개발자들이 절대 다수인 경우도 많이 보았다.

일반적인 SI의 형태라면 워크 스루의 형태만 적합하다. 특정 도메인에 매몰되어 있고, 처리방법이 명쾌하기 때문에, 해당 경험들을 교환하는 것으로도 충분하기 때문이다. 그리고, 자동화된 테스트 수행방법을 최대한 갖추어두는 것이 가장 현명하다.

그러므로, 코드리뷰는 어느 정도 솔루션이나 서비스 등을 고려하고 있는 곳에서 더욱 적합하다고 정의한다.

코드리뷰는 특정 제품이나 서비스를 발전적으로 지향하고 있는 경우라면 필수적으로 선택해야 한다. 하지만, 일부 제품의 경우에는 발전적인 지향이 굳이 필요 없는 제품 라인업을 가진 경우에도 굳이 수행할 필요 없다.

그 경우에는 선택적인 코드리뷰를 지향하면 된다. 비용상의 문제 때문에 굳이 코드리뷰를 억지로 진행할 필요는 없는 경우도 많다. 대부분의 소프트웨어 개발은 테스트 케이스를 잘 만들고, 통과시키는 것으로써 충분한 신뢰를 가지면 충분한 경우가 대부분이다.

특히, 시장이 고착상태이거나, 특별한 변화의 폭이 없다면, 그 정도로 충분한 경우가 된다. 다만, 글로벌 서비스나 웹서비스 등의 지속적인 확장이 필요한 경우라면, 코드리뷰는 필수라고 할 수 있다.

코드리뷰가 필요 없는 경우 체크리스트는 다음의 5가지 정도를 체크해보자.

  1. 특정 도메인만 다루는 팀이나 회사의 개발팀인가?
  2. 지난 2~3년 정도 솔루션이 크게 변한 것이 없으며, 향후로도 기업이나 팀에서 투자가 없다고 예정되어 있는가?.
  3. 현재 개발자들이 해당 솔루션에 대한 변화 없는 개발일을 5년 이상하고 있는가?.
  4. 기능 위주의 SI성 업무를 주로 처리하고 있으며, 복잡한 알고리즘은 존재하지 않고, 기술적이거나 기능적인 난이도가 없는가?.
  5. 비용과 일정상 개발팀에게 리소스 투여가 불가능한 상황이며, 요구사항만 증가하고 권한은 사라진 상황인가?

위의 사례에서 1개 이상이라도 체크된다면, 코드리뷰는 성립하기 힘들다. 대부분 단념하고, TDD나 테스트 케이스를 가능한 많이 축적하여 소프트웨어 품질을 올리기를 권장한다.

코드리뷰가 필요한 경우의 체크리스트도 다음의 5가지 정도를 체크해보자.

  1. 다국어와 시장이 다변화된 환경에서 소프트웨어가 구동되어야 하는 변화가 예측되는가?.
  2. 코드의 복잡도가 높으며, 단순 기능 나열의 요구사항이 아니라, 소프트웨어 아키텍처가 별도로 구성되기 시작하였는가?.
  3. 사용자의 경험성을 증가하기 위하여 매우 많은 변화가 예측되는가?.
  4. 현재 개발 중인 서비스는 중단 없이, 지속적으로 발전되어야 하는 서비스라고 정의되었는가?.
  5. 목표 요구사항이 계속 변화하고 있고, 프레임워크를 지향하여 소프트웨어 품질의 요구사항이 매우 중요한 의사결정이 되어있는가?.

위의 케이스에서 하나라도 해당이 된다면, 코드리뷰는 매우 효과적으로 소프트웨어에 의미 있는 결과물들을 얻어 내기 위한 좋은 방법이 된다.

하지만, 다음과 같은 경우도 같이 고려하여야 한다.

코드리뷰의 정도와 질에 대한 검토 리스트의 최소 체크리스트는 다음의 3가지이다. 물론, 이 정의는 조직 내의 아키텍트나 아키텍트 롤을 하는 사람이 결정하는 것이 좋다.

  1. 실험적인 코드인가?
  2. 1~2명 이상이 공동으로 작업하는 코드인가?
  3. 향후 버려질 가능성이 높은 코드인가?

코드리뷰를 하지 않는 경우에는 해당 코드의 repository나 디렉터리를 완전하게 분리하고, 리뷰가 안된 코드를 명쾌하게 구분할 수 있어야 한다. 그리고, 그 정보는 팀 전체에게 공개되어야 한다.

가장 첫 번째는 코딩규칙 가이드라인의 준수 여부를 체크하는 것이다.

개발자들 간의 상호 중요한 것은 스타일 가이드이다. 하지만, 정말 지키기 어려운 것 또한 스타일 가이드라고 할 수 있다. 하지만, 스타일 가이드는 가능한 준수해야 한다. 하지만, 100% 준수하려는 것은 매우 비효율적인 상황을 만들 수 있다. 하지만, 이 경우에 최소한 리뷰어가 제시하는 기준이나 변경 방향에는 대부분 수긍하는 것이 가장 현명하며, 이 부분은 해당 팀의 가장 경험이 풍부한 사람이 리드하는 것이 좋다.

그래서, 소프트웨어 개발에는 경험이 풍부한 아키텍트의 역할과 선임의 역할이 가장 중요하다. 소셜에서 이야기하는 가장 중요한 포인트는 이런 경험이 풍부한 선임 개발자가 있다면, 돈이 얼마가 들더라도 ‘개발팀’에 모셔야 한다! 가 정답일 것이다.

아직까지 이 부분은 ‘공학’으로 해결할 수 없고, ‘엔지니어링’과 ‘경험’에 의존할 수밖에 없다.

주석의 경우에도 ‘가독성’이 충 부한 코드에는 서술할 필요 없다. 이 부분에 대해서는 꾸준한 팀원들 간에 코딩 문화에 대해서 커뮤니케이션하면서 주석의 범위에 대해서 공론화하는 것이 현명하다. 그래서, 소프트웨어 개발은 대부분이 ‘커뮤니케이션’이고 ‘소통’이다. 그래서, ‘팀워크’이 가장 중요한 것이고. 변수의 명칭에 대해서도 ‘명확’하다는 선에서 합의해야 한다.

테스트가 쉽지 않은 구조는 다른 문제를 야기한다. Junit과 같은 단위 테스트 도구로 손쉽게 정의가 가능한 구조가 아니라면, 변경해야 한다.

코드리뷰 후에 분명하고 타당한 지적에도 고집이 세서 변화가 없는 경우에는 한두 번 이야기하고 더 이상 변화가 없다면, 포기하고. 해당 코드를 격리하여 관리하는 것이 현명하다. 팀원들 간에 감정이 상하는 것이 더 위험하다. 사람은 변하지 않는다 감정에 대한 다툼이나 기대를 할 필요가 없다.

UI가 중요한 코드는 해당 코드들이 급변할 가능성이 농후하다. 처음부터 공을 들여서 추상화를 실현하지 않으면, 해당 코드 때문에 프로젝트가 심각해질 수 있다. 사용자에게 더 좋은 경험을 전달하려고 하면, UI코드는 계속 변화를 일으킨다.

테스트 코드 여부? 로직에 대한 검토, 변수 네이밍 검토와 레이아웃에 대한 것들? 에 대해서는 다음과 같이 판단하고 체크해보자.

코드리뷰는 대부분 ‘직관’에 의존한다. 그래서, 정말 어렵고. 경험이 풍부한 사람이 할 수밖에 없다. 다만, 이러한 코드 리뷰 시의 체크리스트 항목을 몇 가지 간단하게 정리할 수 있다. 최소한의 2가지는 꼭 지키자.

코드 리뷰 시의 필수 내용 두 가지는 다음과 같다.

  1. 코드 검토는 1시간 이내에 끝낼 분량으로 검토한다.
  2. 코드는 200라인 이상을 한 번에 검토하지 마라

이 기준이 어겨지면, 리뷰어는 제대로 된 리뷰를 하기 어려울 것이다. 그리고, 이러한 리뷰를 하는 동안 기능에 대한 검토 체크사항에 대해서 나열해 보면 다음과 같이 나열이 될 수 있을 것이다.

  1. 시스템의 요구사항이 제대로 반영되었는가?
  2. 시스템의 설계의 규격대로 구현되었는가?
  3. 과도한 코딩을 하고 있지 않는가?
  4. 같은 기능 구현을 더 단순하게 할 수 있는가?
  5. 함수의 입출력 값은 명확한가?
  6. 빌딩 블록들( 알고리즘, 자료구조, 데이터 타입, 템플릿, 라이브러리, API )등이 적절하게 사용되었는가?
  7. 좋은 패턴과 추상화( 상태도, 모듈화 )등을 사용해서 구현하고 있는가?
  8. 의존도가 높은 함수나 라이브러리 등의 의존관계에 대해서 별도 기술하고 있는가?
  9. 함수의 반환(exit)은 한 곳에서 이루어지고 있는가?
  10. 모든 변수는 사용 전에 초기화하고 있는가?
  11. 사용하지 않는 변수가 있는가?
  12. 하나의 함수는 하나의 기능만 수행하고 있는가?

또한, 스타일과 코딩 가이드에 대해서고 검토하고 리딩을 해야 한다.

  1. 코딩 스타일 가이드를 준수하고 있는가?
  2. 각 파일의 헤더 정보가 존재하는가?
  3. 각 함수의 정보를 코드에 대해서 설명하기에 충분한가?
  4. 주석은 적절하게 기술되어있는가?
  5. 코드는 잘 구조화되어있는가? ( 가독성, 기능적 측면 )
  6. 헤더, 함수 정보를 도구로 추출해서 자동으로 문서화할 수 있는 구조인가?
  7. 변수와 함수의 이름이 일관되게 기술되어 있는가?
  8. 프로젝트의 가이드를 통한 네이밍 규칙을 준수하고 있는가?
  9. 숫자의 경우 단위에 대해서 기술하고 있는가?
  10. 숫자를 직접 서술하지 않고, 상수를 사용하고 있는가?
  11. 어셈블리 코드를 사용하였다면 이를 대체할 방법은 없는가?
  12. 수행되지 않는 코드는 없는가?
  13. 주석 처리된 코드는 삭제가 되었는가? ( 버전 체크가 되었는가? )
  14. 간결하지만 너무 특이한 코드가 존재하는가?
  15. 설명을 보거나 작성자에게 물어봐야만 이해가 가능한 코드가 있는가?
  16. 구현 예정인 기능이 있다면, ToDo주석으로 표시되어 있는가?

가장 중요한 아키텍처에 대한 검토를 잊으면 안 된다.

  1. 함수의 길이는 적당한가? ( 화면을 넘기면 안 된다. )
  2. 이 코드는 재사용이 가능한가?
  3. 전역 변수는 최소로 사용하였는가?
  4. 변수의 범위는 적절하게 선언되었는가?
  5. 클래스와 함수가 관련된 기능끼리 그룹화가 되었는가? ( 응집도는 어떤가? )
  6. 관련된 함수들이 흩어져 있지 않는가?
  7. 중복된 함수나 클래스가 있지 않는가?
  8. 코드가 이식성을 고려하여 작성되었는가? ( 프로세스의 특성을 받는 변수 타입이 고려되어있는가? )
  9. 데이터에 맞게 타입이 구체적으로 선언되었는가?
  10. If/else구분이 2단계 이상 중접되었다면 이를 함수로 더 구분하라
  11. Switch/case문이 중첩되었다면 이를 더 구분하라
  12. 리소스에 lock이 있다면, unlock은 반드시 이루어지는가?
  13. 힙 메모리 할당과 해제는 항상 짝을 이루는가?
  14. 스택 변수를 반환하고 있는가?
  15. 외부/공개 라이브러리 사용하였을 경우에 MIT 라이선스를 확인했는가? GPL의 경우에는 관련된 영역에서만 사용해야 한다.
  16. 블로킹 api호출시에 비동기적인 방식으로 처리하고 있는가?

당연하겠지만, 예외처리 관련 체크리스트도 제대로 검토해야 한다.

  1. 입력 파라미터의 유효 범위는 체크하고 있는가?
  2. 에러코드와 예외(exception)의 호출 함수는 분명하게 반환되고 있는가?
  3. 호출 함수가 어려와 예외처리 코드를 가지고 있는가?
  4. Null포인트와 음수가 처리되는 구조인가?
  5. 에러코드에 대해서 명쾌하게 선언하고 처리하고 있는가?
  6. switch문에 default가 존재하고, 예외처리를 하고 있는가?
  7. 배열 사용시에 index범위를 체크하는가?
  8. 포인트 사용시에 유요한 범위를 체크하는가?
  9. Garbage collection을 제대로 하고 있는가?
  10. 수학계산시에 overflow, underflow가 발생할 가능성이 있는가?
  11. 에러 조건이 체크되고 에러 발생 시 로깅 정보를 남기는가?
  12. 에러 메시지와 에러코드가 에러의 의미를 잘 전달하는가?
  13. Try/catch 에러 핸들링 사용방법은 적절하게 구현되었는가?

요즘 프로그램은 대부분 이벤트성으로 구동되지만, 시간의 흐름에 대한 체크는 프로그램의 뼈대를 이루게 된다. 이 부분에 대해서도 제대로 검토해야 한다.

  1. 최악의 조건에 대해서 고려하였는가?
  2. 무한루프와 재귀 함수는 특이사항이 아니라면 없어야 한다.
  3. 재귀 함수 사용시에 call stack값의 최댓값이 고정되어 있는가?
  4. 경쟁조건이 존재하는가?
  5. 스레드는 정상 생성, 정상 동작하는 코드를 가지고 있는가?
  6. 불필요한 최적화를 통해서 코드 가독성을 희생하였는가?
  7. 임베디드의 경우에도 최적화가 매우 중요하지 않다면, 가독성을 더 중요하게 해야 한다

가장 중요한 검증과 시험에 대해서도 제대로 인지하여야 한다. 그리고, 테스트를 위해서 가능한 최대한 자동화를 하기 위한 방법들을 이용해야 한다.

  1. 코드는 시험하기 쉽게 작성되었는가?
  2. 단위 테스트가 쉽게 될 수 있는가?
  3. 에러 핸들링 코드도 잘 테스트되었는가?
  4. 컴파일, 링크 체크 시에 경고 메시지도 100% 처리하였는가?
  5. 경계값, 음수값, 0/1등의 가독성이 떨어지는 코드에 대해서 충분하게 경계하고 있는가?
  6. 테스트를 위한 fault 조건 재현을 쉽게 할 수 있는가?
  7. 모든 인터페이스와 모든 예외 조건에 대해서 테스트 코드가 있는가?
  8. 최악의 조건에서도 리소스 사용은 문제가 없는가?
  9. 런타임 시의 오류와 로그에 대비한 시스템이 있는가?
  10. 테스트를 위한 주석 코드가 존재하는가?

간혹 등장하는 하드웨어에 대한 테스트도 마찬가지이다. 다음과 같은 기준들을 통해서 검토해야 한다.

  1. I/O 오퍼레이션 코드에 대한 테스트로 하드웨어가 정상적인 동작을 보장하는가?
  2. 최소/최대 타이밍 요구사항에 대해서도 하드웨어 인터페이스가 충족하는가?
  3. 멀티 바이트 하드웨어 레지스터가 read/write오퍼레이션 중에도 값이 바뀌지 않음을 보장하는가?
  4. 시스템이 잘 정의된 하드웨어 상태로 리셋하는 것을 S/W가 보장하는가?
  5. 하드웨어의 전압이 떨어지거나 전원이 차단되는 경우에 잘 처리하는가?
  6. 대기모드 진입 시와 빠져나 올 때에 시스템이 옳게 동작하는가?
  7. 사용하지 않는 인터럽트 벡터가 에러 핸들러에 연결되어 있는가?
  8. EEPROM손상(데이터 깨짐)을 막기 위한 메커니즘이 있는가? ( 쓰기 동작 중 powe loss)등

구체적으로 코드리뷰를 하고자 한다면, 다음의 코드리뷰에 대한 기법과 적당한 방법을 다음과 같이 설명할 수 있다.

이러한 코드 리뷰를 위한 몇 가지 방법들이 알려져 있다. 그것들을 몇 가지 정리하여 보면 다음과 같다. 코드 인스펙션은 가장 정형화된 기법으로 전문화된 코드리뷰팀을 통해서 구분하는 방법이다. 이 방법은 리소스가 풍부하고, 일정에 여유가 있는 경우에만 사용이 가능하다. 대부분 대기업이나 대형 포털에서 구현 가능한 방법이라고 할 수 있다. ( 이런 곳에 있다면 행복해 하자. ~.~ ) 하여간, 비용과 일정 등이 있다면 이 방법이 현명하다. 그리고, 코드리뷰에 대한 품질에 대해서 정량적인 보고와 구성을 만들어 낼 수 있다는 것은 코드 인스팩션의 가장 좋은 장점이다. 이 코드 인스팩션을 하기 위한 롤을 구분하면 다음과 같이 4가지 롤로 구분할 수 있다.

  1. Moderator
    A. 실질적인 매니저로 팀 간의 인터페이스와 리소스, 인프라를 확보하고, 프로세스에 대한 정의와 산출물의 정리를 담당한다.
  2. Reader
    A. 각 산출물을 읽고, 리뷰하고, 방향성을 제시한다. 보통, 지식이 많은 사람이 담당한다.
  3. Designer/Coder
    A. Reader의 지시에 따라서 코드를 검증하고 잠재적인 발견 등의 수정 방안을 만든다.
  4. Tester
    A. 진행 중인 코드와 권장 수정 코드에 대해서 검증한다.

그리고, 코드 인스펙션은 다음과 같은 6단계로 진행된다.

  1. Planning
    A. 계획 수립
  2. Overview
    A. 교육과 역할 정의
  3. Preparation
    A. 인터뷰와 필요한 문서 습득, 툴 환경 구축
  4. Meeting(Inspection)
    A. 각자의 역할대로 수행
  5. Rework
    A. 보고된 Defect 수정
  6. Follow-up
    A. 보고된 Defect가 수정되었는지 확인

이러한 절차를 통해서, 코드 인스팩션이 수행되면, 상당히 명쾌한 리뷰가 진행되게 된다. 하지만, 일정과 비용 문제 때문에 이 작업은 대부분의 스타트업에서는 선택하기 어렵다. 그래서 사용하는 방법 중의 하나가 팀 리뷰이다.

팀 리뷰는 일정한 계획과 프로세스만 따르는 방법으로, 코드 인스펙션보다는 좀 덜 정형화된 방법으로 진행한다. 보통은 일주일에 한번 정도 팀 리뷰를 수행하거나, 특정 모듈이나 기능이 완료되는 시점을 기준으로 테스트 결과를 가지고 리뷰를 하는 방법을 사용한다.

또한, 위험하거나 의견이 필요한 경우에도 팀 리뷰는 유용하다. 일반적인 팀에서 사용하는 방법이다.

하지만, 이 역시. ‘리뷰’에 대한 제대로 된 인식이 없다면, 적용하기 어렵다. 그래서, 가끔 사용되는 방법이고, 과거 국내 SI업체들이 주로 사용하던 방법 중의 하나가 ‘웍쓰로’이다.

웍 쓰루(Walkthrough)는 단체로 하는 코드 리뷰 기법 중에 비정형적인 방법으로, 발표자가 리뷰의 주제나 시간을 정해서 발표하고 동료들로부터 의견이나 아이디어를 듣는 시간을 가지는 방법으로써 주로 사례에 대한 정보 공유나 아이디어 수집을 위해서 사용하는 방법이다.

이 방법은 ‘특정 도메인’에 종속된 코드를 만들거나, 비슷한 SI성 형태의 업무를 수행하는 경우에 적합하다. 그래서, 국내의 SI업체에서는 적극적으로 사용되면 좋겠지만. 이 ‘시간’마저도 부정확하고, 갑을병정의 SI체게에서 ‘정보공유’나 ‘아이디어 수집’과 같은 커뮤니케이션이 자유롭게 일어나는 것은 매우 힘들다.

이 웍 쓰루는 동일한 조직 내에서 동일한 목적의식이 분명한 팀에서나 활용이 가능한 방법이다. 웍 쓰루를 SI에서 시도한 경우에는 대부분 실패했거나, 목적의식이 다르기 때문에 불분명한 결론들이 대부분 도출되었다.

대부분의 국내 스타트업이나 IT 전문기업들은 ‘리뷰’에 대해서 상급 관리자들이 제대로 허락을 해주지 않는다.

대부분은 팀내에서 어떻게든 자체적으로 해보려고 한다. 그래서, 팀장의 권한 선에서 적절하게 리뷰를 하는 방법 중의 하나가 Peer review or over the shoulder review방법이다. 이 방법은 보통 2~3명이 진행하는 코드리 뷰로 코드의 작성자가 모니터를 보면서 코드를 설명하고, 다른 한 사람이 설명을 들으면서 아이디어를 제안하거나 Defect를 발견하는 방법이다.

또한, 이 방법은 신입사원이나 인턴사원의 경우에 업무 이해도를 높이면서 해당 코드를 사용할 수 있는 수준으로 활용할 경우에 의미 있는 방법이다. 문제는 이 방법은 개발자의 인력 투입이 거의 두배 이상으로 증가하는 것으로써, 고품질의 영역을 개발하거나, 빠른 시간 안에 신입 개발자의 업무 이해도를 높이는 경우가 아니라면 시행하지 않는다.

이렇게도 리뷰가 진행이 되지 않으면, Passaroud는 돌려 보기 방법을 사용한다. 이 방법은 원래 상세한 리뷰 방법은 아니다. 온라인이나 실시간성이 아니라, 리파지토리나 이메일 등을 사용하여 천천히 리뷰하는 방식에 해당하는데, 속도는 느리지만, 중요한 코드이거나, 제품의 기능 개선이 필요한 경우에는 아주 의미가 있다. 보통은 제품의 기능 개선을 위하여 사용하는 방법이다.

이처럼 리뷰의 방법에는 다양한 방법이 있지만, 결론적으로는 어느 정도 개발 조직이 서로 커뮤니케이션하고, 목적의식을 통일하고, 적절한 시간 분배를 통해서 리뷰를 할 수 있는 시간을 만들어 내느냐가 리뷰의 핵심이라고 할 수 있다.

리뷰를 통해서 소프트웨어의 품질을 끌어올리고, 개발자들과 소통하고, 방향성을 만들어 내며, 새로운 기능 개선 작업을 위해서 리뷰는 다양하게 활용된다. 어떤 관점으로 리뷰를 할 것이고, 어떤 관점으로 리뷰라는 프로세스를 개발 프로세스에 탑재할 것인가에 대해서 진지하게 고민하는 것. 그것이 아키텍트의 첫 번째 역할 아닌가 한다.

profile
소프트웨어 개발자로서 벤처/스타트업의 문제 프로젝트를 해소하고, 팀빌딩을 하는 재미로 삶을 사는 글쓰는 흰머리 개발자. (백세코딩)

3개의 댓글

comment-user-thumbnail
2020년 7월 1일

감사합니다. 너무나 도움되고, 공부가 되는 글이었습니다.
개발자로서 부족함이 많아서 항상 고민하고, 나약한 자기연민에 빠지는 경우가 많은데,
다시 마음을 다잡을 수 있는 계기가 되었습니다.
감사합니다.

답글 달기
comment-user-thumbnail
2020년 9월 27일

좋은글 감사합니다!

답글 달기
comment-user-thumbnail
2021년 12월 12일

코드리뷰를 할 수 환경이 아니라면(급박하게 신제품, 새로운 기능을 출시해야 하는 스타트업) 테스트 코드로 코드리뷰를 어느 정도 대체할 수 있다는 거군요.
그렇게는 생각을 안 해봤는데, 고맙습니다 :)

답글 달기