LabHub

블로그

코드 리뷰 완전 가이드: 리뷰를 프로세스로 설계하기

한국어English日本語

들어가며

이 블로그에는 코드 리뷰를 다룬 글이 이미 있습니다. 코드 리뷰의 대화법가르치는 코드 리뷰, 상처 주는 코드 리뷰는 둘 다 말이 어떻게 가서 어떻게 닿는지를 다룹니다. 좋은 글이지만, 그 글들이 다루지 않는 층이 하나 있습니다.

이 글은 리뷰를 대화가 아니라 시스템으로 봅니다. 처리량이 있고, 지연 시간이 있고, 대기열이 있고, 소유권이 있는 프로세스입니다. 같은 팀에서 같은 사람들이 똑같이 친절하게 말해도, 변경 크기가 800줄이고 첫 응답까지 사흘이 걸리면 리뷰는 실패합니다. 반대로 프로세스가 잘 설계되어 있으면 평범한 코멘트도 제 역할을 합니다. 리뷰 품질 문제의 상당 부분은 말투가 아니라 배치의 문제입니다.

기준으로는 Google의 엔지니어링 관행 문서 두 편을 씁니다. 공개된 문서 중 승인 기준과 응답 속도를 가장 구체적으로 규정한 자료이고, 이 글의 인용은 모두 그 원문에서 가져왔습니다.


1. 리뷰가 실제로 사는 이유 네 가지

"리뷰는 버그를 잡기 위한 것"이라는 전제로 프로세스를 짜면 대부분 실패합니다. 결함 발견은 네 가지 목적 중 하나일 뿐이고, 심지어 가장 확실한 것도 아닙니다.

목적이 다르면 프로세스도 달라집니다. 결함 발견이 목적이면 도메인을 아는 한 명이 깊게 보는 것이 낫고, 지식 전파가 목적이면 잘 모르는 사람이 함께 보는 것이 낫습니다. 두 목적을 한 리뷰에 동시에 얹으면 둘 다 어중간해집니다. 팀이 어느 목적을 사는지 명시하지 않으면 리뷰어마다 다른 기준으로 보게 되고, 그 불일치가 작성자에게는 "사람마다 말이 다르다"로 체감됩니다.


2. 승인 기준을 문서화하기

2-1. 기준이 없으면 리뷰어의 취향이 기준이 된다

리뷰가 가장 크게 무너지는 지점은 승인 기준이 암묵적일 때입니다. 어떤 리뷰어는 완벽을 요구하고 어떤 리뷰어는 대충 넘기면, 작성자는 리뷰어 배정 결과에 따라 통과 여부가 갈리는 경험을 합니다. 이건 공정성 문제이기 이전에 예측 가능성 문제이고, 예측할 수 없는 프로세스는 우회됩니다.

Google의 리뷰어 기준 문서는 이 지점에 한 문장을 제시합니다. "In general, reviewers should favor approving a CL once it is in a state where it definitely improves the overall code health of the system being worked on, even if the CL isn't perfect."

이 문장의 핵심은 두 부분입니다. 판정 대상이 변경 자체의 완성도가 아니라 시스템 전체 코드 건강의 방향이라는 것, 그리고 완벽하지 않아도 승인한다는 것입니다. 기준이 "완벽"이면 승인은 리뷰어의 인내심에 달리고, 기준이 "방향"이면 판정은 재현 가능해집니다.

2-2. 무엇이 근거가 되는가

같은 문서는 의견 충돌의 해결 순서도 정합니다. 기술적 사실과 데이터가 의견과 개인 취향을 이깁니다. 스타일 문제는 스타일 가이드가 권위이고, 가이드에 없으면 개인 취향이 아니라 기존 코드와의 일관성을 따릅니다. 이 순서가 명시되어 있으면 "내 취향으로는"이라는 코멘트가 자연스럽게 줄어듭니다.

2-3. 팀 문서에 넣을 최소 항목

승인 기준 (한 장)

승인한다        시스템의 코드 건강이 분명히 나아지는 방향이면
                완벽하지 않아도 승인한다
승인하지 않는다  정확성 결함 / 보안 문제 / 되돌리기 어려운 인터페이스 결정 /
                롤백 경로 없음 / 테스트 없이 동작이 바뀜
근거 우선순위    기술적 사실·데이터 > 스타일 가이드 > 기존 코드와의 일관성 > 개인 취향
막지 않는 코멘트  'Nit:' 접두사를 붙이고, 작성자가 넘겨도 된다

이 한 장이 있으면 리뷰 논쟁의 상당수가 문서를 가리키는 것으로 끝납니다. 없으면 매번 처음부터 다시 협상하게 됩니다.


3. 변경 크기가 거의 모든 것을 결정한다

3-1. 크기는 다른 모든 지표의 상류에 있다

리뷰 프로세스에서 손댈 수 있는 변수 중 효과가 가장 큰 것은 리뷰어의 성실성이 아니라 변경 크기입니다. 크기가 커지면 다음이 동시에 나빠집니다.

3-2. 크기를 줄이는 구체적 방법

3-3. 크기 규칙을 운영하는 법

절대 줄 수 상한을 규칙으로 못 박으면 우회가 생깁니다. 대신 크기에 따라 절차를 바꾸는 방식이 잘 작동합니다. 일정 규모를 넘으면 리뷰 요청 전에 설계 합의를 먼저 요구하거나, 분할 계획을 본문에 적게 하는 식입니다. 작성자가 "왜 이렇게 커졌는지"를 한 줄로 설명하게 하는 것만으로도 상당수가 스스로 쪼개집니다.


4. 지연 시간 — 1영업일 규칙과 그 근거

4-1. 규칙

Google의 리뷰 속도 문서는 상한을 명시합니다. "One business day is the maximum time it should take to respond to a code review request (i.e., first thing the next morning)." 그리고 "If you are not in the middle of a focused task, you should do a code review shortly after it comes in"이라고 덧붙입니다.

주의할 것은 이 규칙이 응답 시간에 대한 것이지 승인 시간에 대한 것이 아니라는 점입니다. 같은 문서는 개별 응답의 지연이 전체 소요 시간보다 중요하다고 설명합니다. 리뷰가 여러 번 오가더라도 각 왕복이 빠르면 전체 경험은 좋고, 왕복 한 번에 사흘이 걸리면 두 번만 오가도 일주일이 사라집니다.

4-2. 왜 속도가 그렇게 중요한가

같은 문서는 두 가지 근거를 제시합니다. 하나는 "Most complaints about the code review process are actually resolved by making the process faster"입니다. 리뷰 프로세스에 대한 불만 대부분이 실제로는 속도 문제라는 것입니다. 다른 하나는 파급 효과입니다. "Slow reviews also discourage code cleanups, refactorings, and further improvements to existing CLs."

두 번째가 더 중요합니다. 리뷰가 느리면 비용이 큰 변경만 남습니다. 정리와 리팩터링은 급하지 않으므로 큐에서 밀리고, 밀리는 것을 아는 사람은 애초에 시작하지 않습니다. 그렇게 코드 건강이 서서히 나빠집니다. 리뷰 지연은 리뷰 품질 문제가 아니라 기술 부채 축적 경로입니다. 부채가 쌓이는 경제 구조는 리팩터링의 경제학에 정리되어 있습니다.

4-3. 집중 시간과의 충돌

같은 문서는 집중 작업 중에는 리뷰를 위해 흐름을 끊지 말라고도 말합니다. 이 둘을 동시에 만족시키려면 리뷰를 인터럽트가 아니라 일정으로 다뤄야 합니다.


5. 무엇을 사람이 보고 무엇을 자동화로 밀어낼 것인가

사람의 리뷰 예산은 한정되어 있습니다. 기계가 더 잘하는 것을 사람이 보고 있으면, 사람만 볼 수 있는 것을 볼 시간이 사라집니다.

항목담당이유
포맷, 임포트 정렬, 줄 길이자동화논쟁 대상이 아니고 판정이 결정적
린트 규칙, 미사용 변수자동화규칙으로 표현 가능, 예외는 설정으로
테스트 실행, 빌드, 타입 검사자동화사람이 확인하면 누락이 생김
의존성 취약점, 시크릿 유출자동화목록 대조 작업, 사람이 놓침
변경분 커버리지 하한자동화관문으로 명시 가능
의도와 구현의 불일치사람요구사항 맥락이 필요
인터페이스와 이름사람되돌리기 비싸고 판정이 맥락 의존
실패 처리와 롤백 경로사람운영 지식이 필요
테스트가 실제 위험을 덮는가사람커버리지 숫자로 대체 불가
이 변경이 필요한가사람도구가 물을 수 없는 질문

원칙은 하나입니다. 한 번이라도 리뷰에서 반복된 지적은 자동화 후보입니다. 같은 코멘트를 세 번 썼다면 그건 사람의 일이 아니라 규칙의 일입니다. 자동화로 옮길 수 없다면 최소한 문서로 옮겨서 매번 협상하지 않게 만듭니다.

AI 리뷰 도구도 이 표의 왼쪽 열을 넓히는 방향으로 봅니다. 다만 자동 제안은 승인이 아니라 코멘트로 취급하는 편이 안전합니다. 판정 책임이 사람에게 남아 있지 않으면 아무도 읽지 않는 승인이 쌓입니다.


6. 소유권과 승인 규칙

6-1. 누가 승인할 수 있는가

소유권 규칙이 없으면 두 가지 실패가 번갈아 나타납니다. 아무나 승인할 수 있으면 도메인을 모르는 사람이 통과시키고, 특정인만 승인할 수 있으면 그 사람이 병목이 되고 휴가 때 팀이 멈춥니다.

실무에서 잘 작동하는 구성은 경로별 소유자 목록을 코드에 두고, 소유자 그룹은 최소 3명 이상으로 유지하는 것입니다. 소유자가 1명인 경로가 남아 있다면 그건 리뷰 규칙 문제가 아니라 버스 팩터 문제입니다.

6-2. 논쟁: 승인 몇 개가 필요한가

여기서 팀마다 답이 갈립니다.

절충안으로 경로별 차등이 널리 쓰입니다. 대부분의 경로는 1인, 인증·결제·마이그레이션 같은 고위험 경로만 2인으로 두는 방식입니다. 규칙이 코드에 있으면 예외 협상이 줄어듭니다.

6-3. 논쟁: 리뷰가 병합을 막아야 하는가

더 근본적인 논쟁도 있습니다. 트렁크 기반 개발이나 페어 프로그래밍을 하는 팀 중에는 리뷰가 병합을 막지 않아야 한다고 보는 쪽이 있습니다. 페어로 작성하면 이미 두 사람이 본 것이고, 병합 후 리뷰가 오히려 배치 크기를 줄여 통합 빈도를 높인다는 주장입니다.

롤백이 몇 분 안에 끝나고 카나리가 있는 팀과, 배포가 월 1회이고 되돌리기가 어려운 팀의 답은 같을 수 없습니다. 어느 쪽을 택하든 그 선택이 어떤 전제 위에 있는지 적어 두는 편이 좋습니다.


7. 코멘트의 등급 — 막는 것과 막지 않는 것

7-1. 등급이 없으면 모든 코멘트가 차단으로 읽힌다

작성자 입장에서 가장 소모적인 상황은 어떤 코멘트를 반드시 반영해야 하는지 모르는 것입니다. 열 개의 코멘트가 같은 무게로 보이면 전부 반영하거나 전부 무시하게 됩니다.

Google 문서는 여기에 간단한 관행을 제시합니다. 반드시 반영할 필요가 없는 다듬기 제안에는 "Nit: " 접두사를 붙여 작성자가 넘길 수 있게 하는 것입니다. 이 관행을 조금 확장해 등급을 명시하면 왕복이 눈에 띄게 줄어듭니다.

Blocking:  반영하지 않으면 승인하지 않음 (정확성·보안·되돌리기 어려운 결정)
Nit:       다듬기 제안, 작성자가 넘겨도 됨
Question:  이해를 위한 질문, 답만 하면 됨
FYI:       이번 변경과 무관한 정보 공유
Later:     별도 이슈로 남길 후속 작업 (여기서 처리하지 않음)

접두사 다섯 개를 도입하는 비용은 거의 없고, 효과는 즉각적입니다. 특히 Later 등급이 있으면 "이왕 여는 김에"로 변경이 부풀어 오르는 현상이 줄어듭니다.

7-2. 논쟁: 코멘트를 단 채 승인하는 것이 건강한가

이것도 팀마다 갈립니다.

등급 체계가 있고 이행률이 높으면 코멘트 승인은 잘 작동하고, 등급도 없고 이행 여부를 아무도 보지 않는다면 그건 사실상 무조건 승인입니다. 제도를 도입하기 전에 이행률을 먼저 재 보는 편이 낫습니다.


8. 합의가 안 될 때의 에스컬레이션

리뷰 프로세스에서 가장 자주 빠져 있는 부분이 이것입니다. 대부분의 팀은 합의되는 경우만 가정하고 규칙을 만듭니다.

Google 문서는 원칙을 짧게 제시합니다. "Don't let a CL sit around because the author and the reviewer can't come to an agreement." 교착 자체가 비용이라는 것입니다.

실무 절차로 옮기면 이렇습니다.

1단계  왕복 2회 안에 해결되지 않으면 비동기 코멘트를 중단한다
       (텍스트로 세 번 이상 오가는 논쟁은 거의 수렴하지 않는다)

2단계  15분 통화나 대면으로 옮기고, 결론을 리뷰 스레드에 요약해 남긴다
       (대화로 옮기되 기록은 리뷰에 남아야 한다)

3단계  그래도 안 되면 판정 근거를 명시한다
       기술적 사실·데이터 > 스타일 가이드 > 기존 코드와의 일관성

4단계  판정자가 필요하면 미리 정해 둔 역할이 결정한다
       (해당 영역 소유자 → 테크 리드 순서를 문서에 적어 둔다)

5단계  결정을 문서에 반영한다
       같은 논쟁이 두 번 일어났다면 그건 가이드가 없는 것이다

핵심은 3단계와 5단계입니다. 근거의 우선순위가 미리 정해져 있으면 논쟁이 취향 대결로 흐르지 않고, 결론을 문서로 되먹이면 같은 논쟁이 반복되지 않습니다. 5단계가 없으면 팀은 매 분기 같은 논쟁을 다시 합니다. 리뷰에서 주장을 설득력 있게 쓰는 방법은 글로 설득하기에 정리되어 있습니다.


9. 리뷰 프로세스를 측정하는 지표와 그 오용

9-1. 볼 값어치가 있는 지표

DORA는 속도와 안정성이 상충 관계가 아니라고 말합니다. "DORA's research has repeatedly demonstrated that speed and stability are not tradeoffs." 리뷰를 빠르게 만들었더니 변경 실패율이 올랐다면 절충이 아니라 다른 문제가 있는 것입니다.

9-2. 개인 지표로 쓰는 순간 망가진다

리뷰 지표는 개인 평가에 붙는 순간 전부 왜곡됩니다.

그래서 지표는 사람이 아니라 프로세스에 붙입니다. 첫 응답 시간이 나쁘면 그건 특정인의 게으름이 아니라 배정 규칙과 슬롯 설계의 문제로 봅니다. 변경 크기 꼬리가 길면 작성자를 지적하는 대신 분할 절차를 만듭니다.

또 하나 중요한 것은 결함 발견 수를 리뷰 효과의 대리 지표로 쓰지 않는 것입니다. 1장에서 봤듯 결함 발견은 리뷰의 네 목적 중 하나이고, 지식 전파나 설계 압력은 이 숫자에 전혀 잡히지 않습니다. 지적이 줄었다는 사실은 리뷰가 무력해졌다는 뜻일 수도 있고, 앞단이 좋아졌다는 뜻일 수도 있습니다. 숫자만으로는 구분되지 않습니다.


퀴즈: 실력을 확인해 보세요

퀴즈 1: 리뷰 불만이 계속 나옵니다. 리뷰어 교육과 응답 속도 개선 중 무엇을 먼저 하나?

정답: 속도를 먼저 봅니다. 첫 응답 시간의 상위 백분위와 변경 크기 분포를 측정한 뒤에 교육을 논의합니다.

설명: Google의 리뷰 속도 문서는 리뷰 프로세스에 대한 불만 대부분이 실제로는 속도를 높이는 것으로 해결된다고 말합니다. 말투 문제로 보이는 갈등의 상당수는 사흘을 기다린 뒤 받은 지적이라서 크게 느껴지는 경우입니다. 또한 느린 리뷰는 정리와 리팩터링 같은 급하지 않은 변경을 먼저 포기하게 만들어 코드 건강을 서서히 떨어뜨립니다. 교육이 불필요하다는 뜻은 아니지만 순서가 있습니다.

퀴즈 2: 리뷰어가 "완벽하지 않으니 더 다듬어 달라"며 승인을 미룹니다. 어떤 기준을 적용하나?

정답: 판정 대상은 변경의 완성도가 아니라 시스템 전체 코드 건강의 방향입니다. 분명히 나아지는 방향이면 완벽하지 않아도 승인합니다.

설명: Google 기준 문서는 리뷰어가 시스템의 코드 건강을 분명히 개선하는 상태가 되면 완벽하지 않더라도 승인하는 쪽을 택해야 한다고 명시합니다. 기준이 완벽이면 승인 여부가 리뷰어의 인내심에 달리고 예측 가능성이 사라집니다. 반드시 반영해야 하는 지적과 다듬기 제안을 등급으로 구분하고, 후자에는 넘길 수 있다는 표시를 붙이는 것이 함께 필요합니다.

퀴즈 3: 평균 첫 응답 시간이 4시간인데 팀은 리뷰가 느리다고 말합니다. 무엇을 확인하나?

정답: 평균이 아니라 상위 백분위와 왕복별 지연, 그리고 대기열에 오래 남은 항목의 크기를 확인합니다.

설명: 체감은 평균이 아니라 꼬리가 만듭니다. 평균 4시간이어도 상위 10%가 사흘이면 그 경험이 팀의 인식을 지배하고, 오래 걸린 항목은 대개 가장 큰 변경입니다. 또한 전체 소요 시간보다 개별 응답의 지연이 중요합니다. 왕복 한 번에 사흘이 걸리면 두 번만 오가도 일주일이 사라집니다. 조치는 개인 독려가 아니라 배정 규칙, 리뷰 슬롯, 임계 시간 초과 시 자동 승격 같은 프로세스 쪽입니다.

퀴즈 4: 관리자가 "리뷰 코멘트 수"를 개인 평가 지표로 넣자고 합니다. 어떻게 답하나?

정답: 리뷰 지표는 프로세스에 붙이고 개인 평가에는 붙이지 않습니다. 대신 첫 응답 시간, 변경 크기 분포, 왕복 횟수, 변경 실패율을 팀 지표로 제안합니다.

설명: 코멘트 수를 재면 의미 없는 코멘트가 늘고, 승인 속도를 재면 읽지 않고 승인하며, 리뷰한 변경 수를 재면 작은 것만 골라 보게 됩니다. 게다가 결함 발견은 리뷰의 네 목적 중 하나일 뿐이라 지식 전파나 설계 압력은 어떤 코멘트 수치에도 잡히지 않습니다. 지적이 줄었다는 사실이 리뷰가 무력해졌다는 뜻인지 앞단이 좋아졌다는 뜻인지 숫자만으로는 구분되지 않습니다.

퀴즈 5: 인터페이스 설계를 두고 작성자와 리뷰어가 코멘트로 나흘째 대립 중입니다. 무엇을 하나?

정답: 비동기 논쟁을 중단하고 짧은 통화나 대면으로 옮긴 뒤, 결론을 리뷰 스레드에 요약해 남기고 문서에 반영합니다.

설명: Google 문서는 작성자와 리뷰어가 합의하지 못한다는 이유로 변경이 방치되지 않게 하라고 명시합니다. 교착 자체가 비용이기 때문입니다. 텍스트로 세 번 이상 오가는 논쟁은 거의 수렴하지 않으므로 채널을 바꾸되 기록은 리뷰에 남겨야 합니다. 그래도 결론이 나지 않으면 기술적 사실과 데이터, 스타일 가이드, 기존 코드와의 일관성 순으로 근거의 우선순위를 적용하고, 미리 정해 둔 판정 역할이 결정합니다. 마지막으로 같은 논쟁이 반복되지 않도록 결론을 가이드에 반영합니다.


마치며

코드 리뷰를 개선하려는 시도가 대개 말투에서 시작해 말투에서 끝납니다. 말투는 중요하지만, 같은 사람이 같은 문장을 써도 변경이 800줄이고 응답이 사흘 뒤에 오면 그 리뷰는 실패합니다. 리뷰는 대화이기 전에 대기열이 있는 프로세스입니다.

프로세스로 볼 때 손댈 곳은 분명합니다. 승인 기준을 한 장으로 적어 판정을 재현 가능하게 만들고, 변경 크기를 줄여 상류를 고치고, 첫 응답 시간에 상한을 두고, 기계가 잘하는 일을 사람에게서 걷어내고, 코멘트에 등급을 붙여 무엇이 차단인지 명확히 하고, 교착에는 미리 정해 둔 출구를 둡니다.

그리고 지표는 사람이 아니라 프로세스에 붙입니다. 리뷰가 느린 것은 대개 누군가 게으르기 때문이 아니라 배치가 그렇게 되어 있기 때문입니다. 배치를 고치는 것이 사람을 재촉하는 것보다 언제나 효과가 큽니다.


참고 자료


이어서 읽기

완전 가이드 시리즈

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다