코드 리뷰 문화에 대한 고찰

2022. 5. 5. 11:32Frontend

 

Overview

코드 리뷰가 무엇인지, 코드 리뷰를 왜 해야 하며, 어떤 방식으로 운영해야 하는지에 대해서 최근에 많은 고민들을 하게 되었습니다. 사람마다, 회사마다, 팀마다 코드 리뷰에 대한 생각들이 각기 다르기 때문에 이를 상황에 맞게 정의하고 방법을 찾는 것이 중요했습니다. 이를 위해 꽤 오랜 시간 동안 프론트엔드 팀에 코드 리뷰 문화를 정착시키기 위한 여러 가지 시도들과 노력들을 했었고, 이를 거치면서 경험한 것들과 생각했던 것들을 정리하려 합니다.

 

 

Why Code Reviews?

풀려고 하는 문제가 무엇인지를 정확히 알아야 그 문제를 풀기 위한 알맞은 노력을 기울이고 방법을 찾아낼 수 있기 때문에 "코드 리뷰를 왜 해야 하는가?"에 대한 명확한 정의를 하는 것이 굉장히 중요하다고 생각했습니다. "좋아 보이는 다른 팀에서 하기 때문에 우리도 해야 한다" 라거나 "이게 요즘 개발 트렌드니까 해야 한다"의 기준으로 도입하는 여러 방법들은 결국 공감과 당위성을 얻지 못한 채, 문화로 정착되지 못하거나 팀의 업무 효율을 떨어뜨리는 경우가 많기 때문입니다. 따라서 코드 리뷰 문화를 제대로 도입하기 이전에 현재 우리 팀이 당면한 문제는 무엇이고, 이 문제를 코드 리뷰를 통해서 어떻게 개선할 수 있을지를 고민하는 것이 우선 과제였습니다.

 

 

Problems

코드 리뷰를 도입해서 풀고자 했던 가장 큰 문제는 "서로 다른 목적조직에서 일하는 개발자들이 서로의 코드를 볼 일이 없다"는 것이었습니다. 10명 정도의 인원이 프론트엔드 팀을 구성하고 있지만, 목적 조직(TF) 단위로 서로 떨어져서 바쁘게 각자 개발하다 보니 서로 다른 TF의 팀원들이 어떤 프로젝트들을 어떻게 개발하고 있는지, 어떤 문제들이 있었고, 이를 어떻게 해결하고 있는지에 대해서 "노력하지 않으면" 잘 알기가 어려웠고, 서로 바쁘기 때문에 "노력해서 다른 TF의 레포를 찾아서 코드를 뜯어보기 어려운" 문제가 있었습니다.

 

A라는 개발자는 오늘 하루 개발하면서 a라는 영역을 새롭게 알게 되었고, B라는 개발자는 b라는 영역을 새롭게 알게 되었는데, A, B개발자가 a, b라는 영역을 모두 알기가 어려웠기 때문에 코드 리뷰를 통해서 100%는 아니더라도 상당 부분 이런 지식의 공유가 이루어지기를 원했습니다.

Solutions

위와 같은 문제를 해결하기 위해 코드 리뷰의 목적을 다음 3가지로 압축했습니다.

 

  1. Learning
    코드 리뷰는 "배움의 장"으로 활용한다. 다른 TF에서 "어떤 일"을 진행하고 있는지, 지금 진행하고 있는 일이 "어떤 화면"으로 보이는지, "어떤 문제"가 있었고, 이를 "어떻게 해결"했는지를 서로가 자유롭게 이야기하는 문화를 만들고 싶다.

  2. Knowledge Exchange
    코드 리뷰를 하면서 다른 구성원들은 코드를 어떻게 작성하는지를 "수시로" "쉽게" 확인하는 문화를 만들고 싶다. 비슷한 문제를 다른 팀원은 이런 방법으로 풀었고, 나는 다른 방법으로 풀었다면, 그런 경험들을 공유하는 장을 만들어서 "서로가 서로의 어깨 위에서" 다음 Step을 밟아나가는 문화를 만들고 싶다.

  3. Increase Code Quality
    1, 2의 과정이 제대로 진행된다면 코드의 품질이 높아질 수밖에 없는 선순환 구조가 만들어질 것이다. 여기서의 코드의 "품질"이란, 안정적인 서비스를 동작하기 위한 기능적 측면뿐 아니라, 많은 인원들이 리뷰하면서 조금씩 다듬어지는 이질감 없는 아키텍처나 프로젝트에 적용되는 비교적 일관성 있는 코드 스타일을 포함하는 넓은 개념이다.

 

Then How?

"코드 리뷰"가 어떤 문제를 해결해야 하는지를 정의했다면, 다음은 이 문제를 해결하기 위해서 "어떠한 방법"을 사용할 것인가를 결정해야 할 것입니다. 이를 위해 다음과 같은 방법들을 도입했습니다.

 

작은 PR & PR Template

코드 리뷰에 참여하는 구성원은 기본적으로 "개발해야 할 것이 아주 많은 바쁜 개발자"라고 가정해야 합니다. 어떤 방법론이 "문화"로 정착되기 위해서는 기본적으로 일상생활에서 그 방법을 수행하는데 드는 노력이 없거나 거의 없어야 하기 때문에 눈코 뜰 새 없이 정신없이 바쁜 개발자가 그럼에도 불구하고 코드 리뷰를 할 수 있도록 하기 위해서는 여러 가지 문화적 지원들이 필요했습니다.

 

가장 먼저 세운 원칙은 작은 PR입니다.

바쁜 와중에 코드 리뷰 요청이 와서 들어갔더니 File Change가 300개인 PR 요청이 있다면 리뷰어가 리뷰를 하기 위해 드는 비용이 매우 클 것입니다. 이런 리뷰 방식은 문화로 정착되기 어렵기 때문에 PR을 인간의 뇌가 변경사항을 어렵지 않게 인지할 수 있을 만큼 Semantic 하게 쪼개는 것을 권장하였습니다. 

 

 

 

 

작은 단위의 PR과 함께 도입한 것은 PR Template입니다. github에서는 PULL_REQUEST_TEMPLATE.md을 생성하면, 해당 프로젝트에서 PR을 생성할 때, 아래와 같이 자동으로 Template을 채워주는 기능을 제공합니다. 이 Template에 다음과 같은 사항을 추가해서 PR 생성 시에 리뷰어가 리뷰하는데 필요한 충분한 정보들을 제공했습니다.

 

  • Summary: 해당 PR의 한 줄 요약
  • Description: 문제를 해결하기 위한 구체적인 노력
  • ScreenShot: 화면의 변경이라면 Before, After 등의 스크린 샷
  • Reference: 관련된 테크 스펙, 기획 문서, 디자인 시안, 참고한 문서 등등의 정보
  • Reproduce: 해당 화면을 리뷰어가 켜서 보고 싶다면 어떤 것들을 수행해야 하는지 (인증방법, 페이지 접속 방법 등등)

 

 

 

CODE OWNER & Random Assign

이렇게 PR을 작게 쪼개다 보면, 당연히 기존보다 PR 수가 많아지게 됩니다. 모든 개발자가 모든 PR을 리뷰할 수 없기 때문에 피로도를 줄이기 위해서 해당 프로젝트에 대해 최종 책임을 갖는 OWNER(복수일 수 있음)를 필수로 추가하고 그 외의 팀원들에 대해서 Random으로 2~3명이 Assign 될 수 있도록 만들었습니다. 

 

 

About code owners - GitHub Docs

People with admin or owner permissions can set up a CODEOWNERS file in a repository. The people you choose as code owners must have read permissions for the repository. When the code owner is a team, that team must be visible and it must have write permiss

docs.github.com

 

예를 들어 Project A의 오너가 M1, M2이고, A1, A2, A3, A4, A5라는 다른 팀원이 있는 상황에서 M1이 Project A에 새로운 PR을 올렸을 때, 오너인 M2는 필수로 Reviewer로 지정이 되고, A1 ~ A5중 랜덤으로 A3, A5가 리뷰어로 지정이 되어 해당 PR에는 총 3명의 리뷰어가 지정이 되는 식입니다. 리뷰어로 지정이 되면, Slack과 연동해둔 Github App에 알림이 오게 되어 쉽게 해당 PR로 들어가서 리뷰를 진행할 수 있습니다.

 

 

Slack Integration

slack에 github 앱을 연동하는 것 외에도 여러 가지 장치들을 통해서 "큰 노력을 들이지 않고" 코드를 리뷰할 수 있도록 몇 가지 커스텀 슬랙 애플리케이션을 연동했습니다. CloudScheduler - CloudFunction를 사용해서 Slack의 Integration에 정기적으로 메시지를 보내는 식으로 구현하였습니다.

 

첫 번째는 PR Dashboard입니다.

일주일 동안 팀원들이 각자 몇 개의 PR을 생성하고, 몇 개의 코멘트를 달았는지를 대시보드의 형태로 보여주고, 이들의 총합이 가장 많은 사람을 그 주의 Code Review King으로 표시도 해줍니다. 구성원들이 어느 정도로 PR을 적극적으로 하는지도 확인할 수 있을뿐더러, 팀 전체의 PR개수, 리뷰 개수의 합도 알려주어서 팀이 전반적으로 리뷰를 "잘게 쪼개서 많이 하고 있는지"를 확인할 수 도 있습니다.

 

 

두 번째는 Stale PR Alarm입니다.

github을 slack과 연동해두어도 보지 못하고 넘어가는 경우들이 있어서, PR이 생성된 지 24시간이 지났는데도 아직 리뷰가 하나도 없는 PR들이 있다면 매일 아침 9:30에 해당 PR와 리뷰어들을 멘션 해줍니다. "아차"하면서 빠르게 리뷰하는 경우도 많고, 해당 PR이 있었는지도 몰랐던 다른 팀원들이 들어가서 리뷰를 해주기도 합니다.

 

 

 

Netflix Feedback Principles

코드 리뷰에 대한 여러 글들을 읽어보면, 리뷰를 주고받는 것도 결국 사람들이 하는 일이라서 오가는 말에 상처를 받거나 감정이 상하는 경우들이 더러 있는 경우가 많습니다. 따라서 피드백을 주고받을 때 몇 가지 원칙을 정리했으며, 이는 Netflix의 "규칙 없음"에서 상당 부분 기인했습니다.

 

  1. AIM TO ASSIST
    “피드백은 선의에서 비롯되어야 한다.” 구체적인 행동 변화가 상대방 개인이나 회사에 어떻게 도움이 되는지 분명히 설명해야 한다.
    -> 즉, "실제로 이런 부분을 개선하면 이런 부분에서 더 나아질 거라 생각하는데 어떻게 생각하시나요?"와 같이 실제로 이 리뷰를 받아들였을 때 예상되는 좋은 점들에 대해서 분명하게 설명해주어야 합니다.

  2. ACTIONABLE
    ”실질적인 조치를 포함해야 한다" 피드백은 받는 사람의 행동이 변화되는 것에 초점을 맞춰야 한다.
    -> 즉, 그냥 "맘에 안 들어요", "조금 어색해요"가 아니라, "어떤 부분이 조금 어색하고, 나중에 이런 문제가 생겼을 때 대응하기가 어려울 수 있을 것 같으니 이렇게 하는 건 어떨까요?"와 같이 구체적으로 제기한 문제를 어떻게 해결하는 것이 좋을지 알려주어야 합니다.

  3. APPRECIATE
    비판을 받으면 변명부터 하려 드는 것이 인간의 자연스러운 본능이다. 피드백을 받으면 이런 자연스러운 반응을 자제하고 이렇게 자문해 봐야 한다. “어떻게 해야 상대방의 고언을 신중하게 듣고 열린 마음으로 그 의미를 짚어보며, 수세를 취하거나 화를 내지 않고 감사한 마음을 표현할 수 있을까?”
    -> 리뷰를 받는 사람은 리뷰어가 1, 2의 관점으로 리뷰를 해주었다는 것을 기억하고 우선 피드백에 감사를 표시하고, 이걸 어떻게 반영할 수 있을지 고민해야 합니다. 또한 리뷰어는 리뷰를 할 때, 몰랐던 사실을 배웠거나, 상대방이 잘 한 부분들이 있다면 그 부분에 대해서도 충분히 감사와 격려를 표시하는 것을 권장합니다.

  4. ACCEPT OR DISCARD
    진심을 담아 고마움을 표현하되, 피드백의 수용 여부는 “전적으로" 받는 사람에게 달렸다는 사실을 이해한다.
    -> 코드 리뷰를 해준 사람은 "자신의 의견을 정확하고 친절하게 전달하는 것에" 집중하고, 이것을 상대방이 수용할지, 아닐지에 대해서까지 신경 쓰지 말아야 합니다. 수용할지 아닐지를 결정하는 것은 해당 프로젝트의 오너인 상대방의 몫이어야 합니다.

 

Conclusion

이렇게 몇 가지 원칙들을 정하고 코드 리뷰 문화를 조금 운영한 결과, 매주 PR의 개수와 리뷰의 개수가 우상향하고 있는 것을 확인할 수 있었습니다. 특히 바로 이전 주에는 9명의 구성원이 192개의 PR와 200개의 Review Comment를 남겼습니다. 

 

 

코드 리뷰가 중요하다는 것은 대부분의 개발자들이 알고 있고, 그중 상당수가 "어떻게" 코드 리뷰를 해야 하는지에 대한 나름의 방법과 철학을 가지고 있을 것입니다. 하지만 이것을 "팀의 문화"로 정착시키는 일은 또 다른 일이며, 많은 주의와 노력을 필요로 하는 일인 것 같습니다. "문화"라는 것이 한번 정착되면 자연스러워서 새로운 사람들도 자연스럽게 따라가게 되고, 바꾸기가 어렵지만, 그만큼 처음에 정착시키는 것이 어려운 성격을 띠는 것 같습니다. 좋은 문화를 팀에 잘 정착시키기 위해서는 가장 먼저 해당 문화에 대한 팀의 공감대를 얻어야 할 것이며, 그 공감대를 바탕으로 적은 노력으로, 최대한 자연스럽게 문화를 녹이는 여러 장치들을 마련하는 것이 중요한 것 같습니다.

반응형

'Frontend' 카테고리의 다른 글

[Web.dev] Fast (4) - Lazy Loading  (2) 2022.06.01
모노레포의 문화적 의의  (0) 2022.05.30
[Nextjs] How Image Optimization Works  (2) 2022.04.30
[Web.dev] Fast (3) - Image Optimization  (0) 2022.04.30
[Web.dev] Fast (2) - Performance Budget  (0) 2022.04.22