2022. 6. 26. 17:51ㆍETC/Software Engineering
본 포스팅은 Software Engineering at Google의 Code Review Flow 내용을 정리한 내용입니다.
해당 내용은 O'reilly에서 출간하고, 저자에 의해 공개된 Software Engineering at Google을 바탕으로 참고하여 정리한 내용입니다.
내용이 재밌기도 하고 기록하고 싶은 내용이 많아서 몇 가지 정리해볼 예정입니다.
이번 주제는 코드리뷰와 관련된 내용입니다.
코드 리뷰는 ‘버그가 코드베이스로 침투하기 전에 잡아낸다’처럼 확실하고 쉽게 납득되는 이점을 제공합니다.
구글에서 잘 관리되고 있는 코드리뷰 문화를 알아보고 코드리뷰에 대한 이점과 필요성에 대해 다룹니다.
여기서 주목할만한 단어가 있는데요. 바로 LGTM 입니다.
LGTM 란 'looks good to me'의 약자로, "변경을 검토한 결과 표준에 부합하며 미해결된 코멘트 해결 후 커밋해도 좋다"는 의미입니다. 흔히 코드리뷰에서 볼 수 있는 코멘트입니다.
배울 내용이 특히 더 많고, 공감가는 부분도 많아서 반드시 다루고 싶던 내용입니다.
내용이 9장과 19장을 아울러 다뤄서 조금 많았지만, 한번쯤 생각해볼 만한 가치가 있는 내용이었습니다.
Code Review Flow
구글은 코드 리뷰를 보통 다음 절차대로 진행한다.
STEP 1. Create Change
코드의 변경 및 분석
작성자가 자신의 작업 공간에서 코드베이스에 적용할 변경사항을 작성한 후 해당 시점을 스냅샷으로 만든다.
스냅샷은 코드 리뷰 도구에 업로드하는데, 구글 in-house 시스템인 Critique(크리틱)이라는 도구이며 자동 코드 분석(automatic code analyzers) 툴이다. 현재 코드베이스와 diff를 떠서 코드가 어떻게 달라졌는지 평가한다.
STEP 2. Request Review
리뷰 요청
코드 작성자가 Critique을 통한 결과에 만족하고 셀프 리뷰(self-review)에 만족한다면, 한 명 이상의 Reviewer에게 리뷰 요청을 보낸다.
STEP 3. Comment
변경 사항 코멘트
리뷰어들은 코드 리뷰 도구에서 변경을 열고 해당 diff에 댓글로 의견을 남긴다.
작성 자에게 해결해야 할 문제를 던져주거나, 단순히 유용한 정보를 제공해주기도 한다.
위의 노란 부분이 리뷰어가 추가한 코멘트이다.
이 때, 요청받은 리뷰어가 아니어도 누구나 댓글을 달 수 있다.
STEP 4. Modify change, reply to comments
수정 및 코멘트 답장
코드 작성자는 피드백을 기초로 변경을 수정하고 새로운 스냅샷을 업로드한 후 리뷰어들에게 회신한다.
3, 4단계인 "Comment"와 "Modify change, reply to comments"는 여러 차례 반복될 수 있다.
STEP 5. Change approved
수정 승인
리뷰어들이 변경 내용에 모두 만족하면 LGTM 태그를 달아준다.
LGTM는 'looks good to me'의 약자로, 변경을 검토한 결과 표준에 부합하며 미해결된 코멘트 해결 후 커밋해도 좋다라는 의미로 통한다. LGTM은 원칙적으로는 한 개만 얻어도 되지만, 일반적으로 모든 리뷰어가 LGTM을 달아주는 게 관례로 통한다.
STEP 6. Commit change
변경사항 Commit
변경에 LGTM이 달리고 모든 댓글을 해결하고 변경이 승인되면 작성자는 코드베이스에 커밋할 수 있다.
Code is a Liability
Liability; 법적 책임, 골칫거리, 부채
코드는 없어서는 안되는 부채이다.
존재만으로 어느 순간 누군가가 유지보수해야할 대상이 된다.
중복 코드는 짜는 시간 자체도 낭비이기도 하지만 유지보수 중 수정 비용이 커지는 것이 당연하다.
코드 전체를 새로 짜는 일은 흔치 않아서 ‘밑바닥부터 만들고 있다면 분명 잘못하고 있는 거야’라는 말도 있다.
라이브러리나 유틸리티 코드는 특히 더 그렇다.
Code Review Works
구글에서는 어떤 변경이든 ‘Approval’을 얻으려면 아래의 세 가지 측면에서의 리뷰를 통과해야 한다.
✔️ Correctness & Comprehension
첫째로 다른 엔지니어로부터 정확성 correctness 과 납득성(이해 용이성) comprehension 을 평가받는다.
comprehension는 '이해'라는 의미를 갖는데, 해당 내용에서는 변경 사항에 대한 이해라는 의미가 변경 사항에 대한 납득과 비슷한 맥락이라고 판단해서 번역했습니다. 정말 단순히 '이해'의 의미를 내포할 수도 있습니다.
즉, 작성자가 의도한 작업을 코드가 적절하게 수행하는지를 본다.
✔️ Approval from code owner
둘째, 변경되는 코드를 관리하는 코드 오너 code owner 들 중 한명에게 변경 코드가 적절하다는 (특정 디렉터리에 체크인해도 좋다는) 승인을 받는다. 코드 오너는 자신이 맡은 디렉터리의 문지기 역할을 한다. 해당 코드 변경은 어떤 엔지니어나 제안할 수 있고 LGTM도 제안자 외의 모든 엔지니어가 달 수 있다. 하지만 코드베이스에 변경을 반영하려면 해당 디렉터리 소유자의 승인이 반드시 필요하다.
변경 작성자가 코드 소유자라면 이 승인은 묵시적으로 받은 게 된다.
소유자 역할은 테크 리드나 해당 영역의 기술 전문가가 맡는다.
✔️ Readability
셋째, 누군가로부터 ‘가독성’ 승인을 받는다.
구글에서 "가독성"은 단순히 이해를 의미하는 것이 아니라 코드를 다른 엔지니어가 유지할 수 있도록 하는 일련의 스타일과 베스트 프랙티스를 가리킨다.
즉, 변경 코드가 해당 언어의 스타일과 Best Practices를 따르고 기대되는 방식대로 작성되었는지를 검사받는다. 가독성 검토자는 회사 전체에서 해당 언어의 가독성 검증성이 보장된 엔지니어 중에 뽑는다.
위 세가지 단계를 다 처리하기에는 많은 시간이 걸릴 것 같고 과해보이지만, 실제로는 대부분 한 명이 위의 세 역할을 진행해서 빠르게 진행된다. 다만, 코드 리뷰의 확장성 (세 개의 역할로 나누면서 더 유연한 리뷰) 때문이다.
Code Review Benefits
✔️ Code Correctness
코드가 정확한지 확인할 수 있다.
코드 정확성 리뷰어는 일차적으로 변경된 코드의 ‘정확성’을 확인해주며, 코드 리뷰가 주는 가장 확실한 이점이다.
적합한 테스트가 갖춰졌나, 설계는 적절한가, 정확하게 동작하나, 효율적인가, 버그는 없나를 살피기 때문에 정확성을 준다.
코드 리뷰가 소프트웨어 버그를 예방하는 효과가 있다는 사실은 이미 많은 연구에서 밝혀졌다.
IBM의 한 연구에서는 버그를 프로세스 초반에 잡아낼수록 (당연하게도) 나중에 발견해 고칠 때보다 시간이 덜 든다고 한다.
코드 리뷰에 들이는 시간은 테스트, 디버그, 회귀 테스트에 투입 되는 시간을 줄여준다.
✔️ Comprehension of Code
변경된 코드를 다른 엔지니어도 잘 이해할 수 있다.
작성자의 관점에 치우치지 않은 피드백을 제공한다.
주어진 변경이 다른 사람에게도 쉽게 이해되는지를 평가할 수 있는 첫번째 관문이다.
코드는 작성되는 횟수보다 읽히는 횟수가 몇 배는 많으므로 이해하기 쉽게 작성하는 게 매우 중요하다.
✔️ Code Consistency
코드베이스가 일관되게 관리된다.
작성자가 작성한 코드는 수많은 사람이 읽고 이해해야 한다.
프로젝트를 진행할 때에도 다른 사람들이 당신의 코드를 읽고 리팩터리해야할 수도 있다.
따라서 코드는 일정한 표준을 따라야 하며, 그래야 조직 안에서 이해되고 유지보수 될 수 있다.
리뷰어는 코드리뷰를 진행하면서 해당 코드가 코드베이스의 표준을 얼마나 잘 따르고, 건강Health한지를 보장해야한다.
✔️ Psychological and Cultural Benefits
심리적, 문화적으로 중요한 이점을 제공하는데, 대표적으로 소유권과 검증이 있다.
팀이 소유권(주인의식)을 더 강하게 느낄 수 있다.
'자신의 것'이 아니라 협업을 통해 만들어지는 '조직의 공동 소유물'임을 인식시켜준다.
또 소유권을 제외한 다른 이유는 바로 검증이다.
아주 뛰어난 엔지니어도 가면 증후군을 겪거나 자기비판이 심할 수 있다.
코드리뷰는 그들의 작업 결과를 검증하고 인정해주는 역할을 해준다.
✔️ Knowledge Sharing
지식이 공유된다.
리뷰 과정에서 아이디어를 교환하고 지식을 공유하게 되는 것이 리뷰어와 작성자 모두에게 이롭다.
리뷰 프로세스는 제안, 신기술 소개, 조언을 통해 리뷰어가 변경 작성자에게 도메인 지식을 전파하도록 이끌어 준다.
FYI(참고로, for your information) 주석으로 가벼운 내용을 전달할 수도 있다.
Best Practices
✔️ Be Polite and Professional
공손하고 전문가답게
리뷰를 하는 엔지니어들에게도 코드리뷰는 긴장되는 일이다. 해당 변경이 본인의 리뷰만 통과하면 코드베이스에 반영될 수 있기 때문이다. 때문에 절대 LGTM을 가볍게 사용하지 않는다. 어떤 피드백과 비평이라도 전문가답게 건네는 일이 중요하다.
일반적으로 리뷰어들은 작성자가 선택한 방식을 존중하고 오직 그 방식에 결함이 있을 때만 대안을 제시해야 한다. 더 특별히 우수한 게 없음을 설명할 수 없다면 해당 코드 작성자의 취향을 받아들여야 한다.
Remember that you are not your code, and that this change you propose is not “yours” but the team’s.
당신의 코드는 당신이 아니며, 당신이 제안하는 코드의 변경은 당신의 것이 아니라 당신의 팀의 것임을 기억해라.
또 하나 중요한 것은 코드 리뷰어가 단 코멘트는 모두 TODO로 받아들여야 한다. 의문없이 수용할 필요는 없지만, 적어도 고민은 해봐야 한다. 동의하지 않는다면 그 사실과 이유를 리뷰어에게 전달해야 한다.
코드 리뷰는 작성자와 리뷰어 모두에게 배움의 기회임을 항상 명심해라.
이는 의견 충돌이나 감정싸움으로 번지지 않게 도와줄 수도 있다.
✔️ Write Small Changes
조금씩 변경하기
코드 리뷰 프로세스를 날렵하게numble 가져가려면 변경을 작게 만들어라.
작은 변경이라고 하면 보통 코드가 약 200줄 이하라는 의미이다.
코드 리뷰는 단 하나의 문제만을 다루는 게 가장 이상적이다.
구글에서는 거대한 변경을 지양하며, 리뷰어는 큰 변경에 대해서는 거부할 권한이 있다.
변경이 크면 그만큼의 시간이 걸리니 작성자가 리뷰를 기다리는 시간도 줄어들고, 버그가 생겼을 때 살펴볼 코드도 적어진다.
큰 기능을 새로 도입할 때는 작은 변경들로는 대응하기 어려운데, 커다란 변경을 관리하는 기법(브랜치 전략)도 존재하긴 한다. 하지만, 감당할 부담이 늘어나는 걸 피할 수는 없다.
✔️ Write Good Change Descriptions
변경 설명 잘쓰기
변경 설명의 첫 줄은 어떤 변경인지를 잘 요약해야 한다.
마치 이메일의 제목처럼 사용하기 때문에 첫 번째 줄은 굉장히 중요하다.
구체적으로 무엇을 왜 변경하는지 알려주는 자세한 설명도 필요하다.
달랑 '버그 수정'만 적으면 리뷰어나 나중에 이력을 살피는 사람에게도 아무런 도움이 안된다.
여러 수정을 했다면, 그 수정 사항들을 열거해서 적어라.
또, 코드의 주석도 자세한 설명을 할 수 있는 방법이다.
리뷰어가 코드를 이해하지 못한다면 구조를 개선하거나 코드 주석이 미흡하다는 신호이다.
코드 리뷰는 당장만이 아니라 후대를 위해 현재 하고 있는 일을 기록하는 행위이다.
✔️ Keep Reviewers to a Minimum
최소한의 리뷰어
대부분의 코드 리뷰는 정확히 한 명의 리뷰어만으로 진행된다.
구글은 변경 승인에 필요한 세 가지 역할(LGTM, 소유자 승인, 가독성 승인)로 분할하여 한 사람이 모두 수행하며 구글 정도의 규모에서도 잘 운영되게 만들었다.
리뷰어는 많아질수록 새로운 시각이 한 스푼씩 더해지며, 결국 수확 체감diminishing returns으로 이어진다.
구글에서는 첫 번째 LGTM이 가장 중요하며, 두 번째부터는 크게 신경 쓸 가치가 없다는 걸 발견했다.
수확 체감이란, 어떤 생산요소의 투입을 고정시키고 다른 생산요소의 투입을 증가시킬 경우 산출량이 점진적으로 증가하다가 투입량이 일정수준을 넘게 되면 산출량의 중가율이 점차적으로 감소하게 되는 현상. 예를 들어 쌀생산을 생각하면 노동이란 생산요소를 추가해도 결국 수확량의 늘어나는 정도는 갈수록 줄어들며 마지막에는 전혀 늘어나지 않게 된다.
✔️ Automate Where Possible
가능한 한 자동화하기
프로세스 중 자동화할 수 있는 요소가 있다면 자동화해라.
기계적인 업무는 도구에게 맡기면 그 만큼을 거두어 드릴 수 있다.
구글에서 가장 중요하게 진보한 내용으로는 정적 검사 자동화가 있다.
거의 모든 코드 리뷰 도구가 프리서브밋presummit과정에서 자동으로 수행되기 때문에 Test, Lint, Formatter 를 작성자가 직접 수행할 필요가 없다. 덕분에 리뷰어가 포맷팅보다 더 중요한 문제에 집중할 수 있게 한다.
'ETC > Software Engineering' 카테고리의 다른 글
Unit Testing - Software Engineering at Google (0) | 2022.07.07 |
---|---|
Documentation - Software Engineering at Google (0) | 2022.06.29 |
A Good Leader - Software Engineering at Google (0) | 2022.06.13 |
Knowledge Sharing - Software Engineering at Google (0) | 2022.06.08 |
Work Well on Teams - Software Engineering at Google (0) | 2022.06.07 |
Backend Software Engineer
𝐒𝐮𝐧 · 𝙂𝙮𝙚𝙤𝙣𝙜𝙨𝙪𝙣 𝙋𝙖𝙧𝙠