왜 우리는 코드리뷰를 하는가?에 대해 사내에 발표하기 위한 자료를 정리하여 올립니다.
이 포스팅은 정답이 아닌 개인적인 의견과 관점이고 팀마다 상황이 다르고 조직마다 지향하는 바가 다르기에 상황에 맞게 적절한 전략으로 코드리뷰를 진행하는 것이 좋다고 생각합니다. :)
Why?
우리는 왜 코드리뷰를 하는가?
-
버그가 될 수 있는 부분을 사전에 파악하기 위해
-
코드의 성능, 가독성을 증가시키기 위해
-
팀 코드 스타일의 일관성 유지시키기 위해
-
새로운 feature 코드를 공유하고 잠수함 패치를 방지하기 위해
-
작업한 사람을 탓하지 않기 위해 (책임을 분배하기 위해)
-
⭐️ 서로의 코드를 통해 배울 수 있음
-
Reviewer를 통해 배우기
val inputStream = new FileInputStream("text.txt"); try { loadDataFrom(inputStream) } catch (exception: Exception) { logger.error(exception) } finally { inputStream.close() } // Reviewer: // kotlin `use`를 사용하면 finally에서 close를 하지 않아도 해당 리소스를 반환하여 // 보다 간결하고 안정적인 코드가 됩니다.
-
Reviewee를 통해 배우기
@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public abstract class Product { @Id private long productId; @Column private String name; } @Entity public class FoodProduct extends Product { @Column private LocalDataTime expirationDate; } @Entity public class ElectronicProduct extends Product { @Column private Int power; } // Reviewer: // 문서를 봐도 정확히 이해가 안되는데 // @Inheritance(strategy = InheritanceType.SINGLE_TABLE)의 역할이 무엇인가요? // Reviewee: // SINGLE_TABLE 전략을 사용하면 abstract Entity의 구현체들에 대한 DB table이 // 하나하나 생성되지 않아 table 관리 및 조회 측면에서 유리합니다.
-
코드리뷰가 단순히 코드를 체크하는 업무의 과정 중 하나가 아니라 좋은 개발자가 되기 위해, 더 좋은 소프트웨어를 개발하기 위한 서로의 노력과 소통의 과정이라고 생각하면 좋을 것 같습니다 :)
How?
Reviewee와 Reviewer의 입장에서 코드 리뷰를 어떻게 대해야할지?
Reviewee
코드리뷰 시 Reviewer 로서
-
Reviewer의 허들을 낮춰줘야한다: 리뷰를 하는 입장에서 리뷰라는 행위가 힘든 일이 되면 안된다.
-
어떤(What) 작업을 왜(Why) 하였고, 어떻게(How) 하였는지에 대해 충분히 context를 전달해준다.
- Github Template, Label, Jira issue card 등을 활용한다.
- 참고
-
변화를 너무 크게 하지 않는다 (e.g. 뱅크샐러드 모든 PR은 200~300줄 이내)
- 빠른 리뷰 가능
- 리뷰어가 리뷰하는 시간이 길어지고 집중도도 떨어짐
- 코드 리뷰 퀄티티 저하 및 버그 가능성을 놓치기 쉬움
- 부득이한 경우 따로 미팅을 통해 해당 작업에 대한 충분한 context를 설명
- 참고
-
commit 의 단위를 잘 나누고 message를 잘 작성하도록 한다
- Reviewer가 전체 file changes를 보면서 어떤 식으로 작업했는지 쫓아가기는 힘들다. commit의 단위를 잘 나눴으면 commit history를 통해 어떤 식으로 작업을 했는지 진행 과정을 살펴보고 코드를 이해하기 편해진다
- 참고:
-
리뷰 우선순위를 고려할 수 있는 label을 달도록 한다.
- 여러 리뷰 요청 시 label을 통해 해당 PR의 Priority를 파악할 수 있도록 한다.
- 참고:
-
Reviewer
코드리뷰 시 Reviewee 로서
-
의견에 대해 논거가 충분해야한다
-
객관적인 사실이 개인의 선호도보다 우선시 되어야한다.
if (someCondition) return doThis(); else if (otherCondition) return doThat(); throw new Error(); // bad 👎 // Reviewer: // if 문에 왜 brace이 없죠? 넣는게 좋지않나요?? // good 👍 // Reviewer: // if 문에 brace를 항상 넣어주세요. // 당장은 이슈가 없어도 위와 같은 코딩 스타일은 추후 크리티컬한 버그가 일어날 요지가 있습니다. // https://embeddedgurus.com/barr-code/2014/03/apples-gotofail-ssl-security-bug-was-easily-preventable/
def getCode(condition: bool) -> int: if condition: return 1 else: return 2 # bad 👎 # A: 삼항연산자로 대체해주세요. # B: 특별한 이유가 있을까요?? # A: 코드가 한 줄이고 더 보기 편하잖아요. <= 주관적 # good 👍 # A: 우리 코딩 컨벤션에 맞춰서 삼항연산자로 대체해주세요.
-
-
리뷰는 최대한 빨리 해주는 것이 좋다 (아무리 늦어도 당일)
- 리뷰를 기다리는 동안 해당 작업은 blocked 상태가 되기 때문에 빠르게 피드백을 준다.
- 사정 상 리뷰가 늦는 경우 언제 리뷰가 가능한지에 대한 피드백을 주어야한다.
- 팀, 조직이 코드 리뷰로 인한 리소스 사용을 충분히 이해하고 인지해야함
- 참고:
-
리뷰 시 해당 코멘트의 강조 여부를 알려주는 것이 좋다
How to make review process better?
Do
-
리뷰 역시
communication
이다-
코드 리뷰 이전에 대화에 있어 기본적인 에티켓을 지켜야한다
-
동료로서 Reviewer의 좋은 코드에 대해서 칭찬을 해주는 것도 중요하다
-
서로 생각과 지식의 차이를 인정하고 이에 대해 건강한 피드백과 좋은 타협점을 내도록 해야한다
def square_numbers(numbers: List[int]) -> List[int]: squared_numbers = [] for num in numbers: squared_numbers.append(num * num) return squared_numbers # bad 👎 # Reviewer: 왜 for 문을 사용한거죠? List Comprehension으로 하는게 더 나을거 같네요 # Reviewee: 왜죠? 결과가 같은데 굳이 변경할 필요가 있나요? 별 차이는 없으니 변경은 안할게요 # good 👍 # Reviewer: # for 문을 사용하는 것보다 List Comprehension이 Python에서 지향하는 바이기도 하고 성능면에서도 우세합니다. # 이 영상(<[https://www.youtube.com/watch?v=Txz7K6Zc-_M](https://www.youtube.com/watch?v=Txz7K6Zc-_M)>)의 5분 20초 쯤 보면 성능에 대해 나와있습니다. # Reviewee: # 좋은 아이디어주셔서 감사합니다만, 다른 분들이 List Comprehension에 대해 충분한 숙지가 되어있지가 않으니 # 쉽게 알아볼 수 있는 for 문을 사용하는 것이 현재 상황에서는 좋다고 생각합니다.
-
참고
-
-
Notification for review request and review comments
- Upsource, Codestream과 같은 IDE 통합 code review tool을 사용하면 실시간으로 리뷰가 이뤄지기 편함
- Slack을 통해 리뷰 요청이나 코멘트 시 알림을 받도록 함
- Scheduled PR reminder
-
Test code를 통해 기능을 수행했을 때 이에 대한 기대값을 보여주면 해당 코드에 대한 사용법을 알기 편하다.
- 그렇기 때문에 테스트 코드의 가독성 또한 중요
- https://helloworld.kurly.com/blog/try-bdd/
Don't
-
Coding convention, style, test 코드 정상 작동 여부를 리뷰한다
⇒ git hooks, github actions, linter, static analysis tool을 통해 자동화 -
approve 후 추가 commit 및 잠수함 패치
⇒ 새로운 commit 시 merge 막기 -
☠️ 교착상태
- Reviewee는 피드백 반영을 하지 않고 리뷰어는 approve하지 않는 상태
- 텍스트 커뮤니케이션은 감정을 전달하기 힘들고 오해의 소지가 많기 때문에 이런 경우 오프라인에서 얘기를 한다
- 이러한 상태가 계속 진행되면 리드와 상의 후에 다른이에게 리뷰를 맡긴다
- 참고
References
- Stackoverflow: How to Make Good Code Reviews Better https://stackoverflow.blog/2019/09/30/how-to-make-good-code-reviews-better/
- Microsoft: How We Do Code Review https://devblogs.microsoft.com/appcenter/how-the-visual-studio-mobile-center-team-does-code-review
- Google: Code Review Developer Guide https://google.github.io/eng-practices/review/
- Oracle: Five Code Review Antipatterns https://blogs.oracle.com/javamagazine/five-code-review-antipatterns
- 스타일쉐어: 우리는 코드 리뷰를 잘하고 있을까요? https://medium.com/styleshare/우리는-코드-리뷰를-잘하고-있을까요-201c12d04d0d
- 뱅크샐러드: 코드 리뷰 in 뱅크샐러드 개발 문화 https://blog.banksalad.com/tech/banksalad-code-review-culture/#리뷰-우선순위-판단을-돕는-d-n-룰
- 로지스팟: 코드리뷰의 진짜 목적은 따로있다 https://blog.logi-spot.com/코드리뷰의-진짜-목적은-따로있다/
'ETC' 카테고리의 다른 글
Double Dispatch를 통해 유연하게 확장하기 (0) | 2022.02.10 |
---|---|
Arrow Core: Tutorials - Functional Error Handling (작성 중) (0) | 2021.12.31 |
WebSocket Server에서 Connection 'close' 이벤트를 받지 못할 때 (1) | 2021.01.06 |
BCrypt로 Password Hashing 하기 (0) | 2021.01.02 |
Sync & Async / Blocking & Non-Blocking (0) | 2021.01.02 |
댓글