2016년 말 이후로 제가 뷰어팀에서 코드 리뷰어 역할을 맡게 되는 경우가 늘어나게 되었습니다. 코드를 직접 작성하는 것과는 또 다른 어려움을 겪으면서 많은 고민을 하게 되었으며, 이 글에서는 이러한 고민과 그에 대한 제 나름의 해결책에 대해 자세히 이야기해보고자 합니다.


좋은 도구에 대한 고민

Git을 사용하면서 GitHub Flow 등의 전략에 따라 브랜치를 적절히 관리하고 있다면 어떤 방법으로든 코드 리뷰를 원활하게 진행할 수 있는 토대가 갖추어진 셈이라고 생각합니다.

이와 더불어 좋은 도구를 사용하면 더 편리하게 리뷰를 진행할 수 있었는데요, 아래와 같은 특징을 가지고 있는 도구가 편리하게 느껴졌습니다.

변경 사항과 코멘트를 불러오는 속도가 빠르다.

일부 도구에서는 남겨진 코멘트의 개수나 리뷰할 코드의 양이 늘어날수록 로딩 속도가 느려지는 현상이 있었고, 이로 인해 코드 리뷰를 진행하는 데 방해를 받게 되는 경우가 있었습니다.

리뷰할 커밋의 범위를 세밀하게 조정할 수 있다.

코드 리뷰를 진행하다 보면 리뷰 -> 리뷰한 내용을 반영 -> 반영된 내용을 다시 리뷰하는 과정을 여러 번 반복하게 됩니다. 이때 이미 리뷰가 완료된 커밋을 제외하거나, 특정 범위에 속한 커밋만을 리뷰하는 기능을 활용하면 검토해야 할 변경 사항의 분량을 줄일 수 있어 훨씬 더 편리했습니다.

확인이 완료된 코멘트를 별도로 관리할 수 있다.

코멘트가 100개가 넘어가는 경우 어떤 코멘트의 내용을 확인했고 어떤 것을 더 검토해야 하는지 혼동되는 경우가 종종 있었습니다. 확인이 완료된 코멘트를 별도로 관리할 수 있는 경우, 반영하지 않은 코멘트를 놓칠 염려가 없어서 안심이 되었습니다.

파일 및 이미지 첨부를 쉽게 할 수 있다.

글로만 리뷰 내용을 전달하기에는 어느 정도 한계가 있고, 그렇다고 구두로만 이야기하면 기록이 남지 않는 문제가 있습니다. 파일을 쉽게 첨부할 수 있는 도구를 사용하면 스크린샷을 이용하는 등의 방법을 통해 더 편리하게 의사소통을 할 수 있어 좋았습니다.

현재 리디북스 뷰어팀에서는 여러 도구를 거친 끝에 GitHub의 풀 리퀘스트 기능을 이용해 코드 리뷰를 진행하고 있습니다.


좋은 프로세스에 대한 고민

좋은 코드 리뷰 프로세스는 좋은 코드를 얻어낼 수 있고, 리뷰어의 부담을 최소화하는 프로세스라고 생각합니다. 아래에서는 이 두 가지 목표를 달성하기 위해 시도해보았던 방법들에 대해 다뤄보겠습니다.

리뷰 시작 전, 무엇을 하는 코드인지 전체적인 역할 파악하기

스스로 깊숙이 파악하지 못한 부분에 대해 리뷰를 하고 코멘트를 남기는 것은 무의미한 일이라고 생각했습니다. 그래서 세부적인 부분을 살펴보기 전에 이 코드가 전체적으로 어떤 목적을 위해 작성되었는지 코드의 작성자와 비슷한 수준으로 파악하려고 노력하였습니다.

이를 위해 관련 문서와 풀 리퀘스트의 내용을 자세히 검토함과 동시에, 변경사항이 적용된 부분을 직접 사용해보며 확인하는 과정을 거쳤습니다. 본격적으로 코드를 검토하기 전에 이 과정을 거치면 아래와 같은 장점이 있었습니다.

어떤 작업이 진행된 것인지 더 깊게 이해할 수 있다.

진행된 작업에 대한 이해도를 높인 후에 리뷰를 시작하는 것은 코드의 각 부분이 작업의 목적에 맞게 작성되었는지 검토하는 데 도움이 되었습니다. 특히 리뷰할 코드의 분량이 많고 작업의 범위가 넓을 때 많은 도움이 되었습니다.

버그를 본격적인 리뷰 전에 확인할 수 있다.

어떤 버그의 경우 수정을 위해서 상당히 많은 코드 변경이 필요할 수도 있습니다. 리뷰가 한창 진행 중일 때 이를 발견하게되면 기존에 리뷰한 코드는 무의미해지고 새로 작성된 코드를 또 검토해야하는 상황이 발생하게 됩니다.

변경된 부분을 직접 사용해보면서 버그를 미리 발견하고 수정을 요청할 수 있는 기회를 가질 수 있었습니다. 이를 통해 리뷰어의 부담을 줄일 수 있었습니다.

하지만 아래와 같은 문제점도 있었습니다.

테스트 자동화가 잘 되어있다면 불필요한 과정이 아닌가?

UI와 직접적으로 연관되어있지 않은 코드에 대해서는 옳은 말이라고 생각합니다. 이러한 경우 코드를 직접 실행해가며 파악하는 것보다는, 좋은 테스트 케이스를 통해 코드를 파악하고 검증하는 것이 더 올바른 방법이라고 생각합니다.

다만 UI와 관련성이 높은 코드, 특히 모바일 앱 코드의 경우 요구사항이 지속적으로 변화할 뿐 아니라 운영체제 버전, 화면 크기, 제조사별 동작의 차이, 보기 설정 등 여러 가지 변인이 많아서 테스트 자동화에 다소 어려움이 있습니다. 또한 직접 눈으로 동작을 보는 것이 해당 코드를 파악하는 데 더 용이한 측면도 있습니다.

거시적인 관점에서부터 리뷰하기

전체적인 구조를 먼저 확인하고, 디테일한 부분을 이어서 리뷰하는 것이 좋았습니다.

예를 들어 데이터베이스 관련 작업의 리뷰를 진행할 때, 세부적인 부분에 대한 리뷰를 진행한 후 나중에서야 모델 클래스의 구성이 부적절하다고 판단하여 수정을 요청하게된다면 이제까지 리뷰했던 것들이 무용지물이 될 것입니다.

이처럼 큰 변화를 가져올 수 있는 거시적이고 핵심적인 부분부터 리뷰하는 것이 리뷰의 부담을 줄이는데 도움이 되었습니다.

최대한 자동화하기

Travis CI와 같은 도구를 이용해 코딩 스타일 준수 여부, 빌드 성공 여부, 테스트 통과 여부를 매번 자동으로 체크하는 것도 많은 도움이 되었습니다.

리뷰어가 일일이 확인하고 언급해야 할 이슈가 줄어들어 리뷰에 걸리는 시간이 줄어들었고, 코딩 스타일처럼 리뷰어가 코멘트를 남기기에 심적으로 부담이 될 수 있는 부분도 덜어낼 수 있었습니다.

코드 작성자 입장에서도 실수를 하더라도 바로 알 수 있어 코드의 품질을 높이는 데 도움이 되었습니다.

리뷰 범위 밖의 문제를 발견한 경우에 대처하기

리뷰를 하다 보면 해당 리뷰와는 연관성이 적지만 중요한 문제를 발견하거나, 리뷰 범위에 존재하는 문제가 리뷰 범위 밖에도 존재하는 경우가 있었습니다.

처음에는 그런 문제들을 다 같이 해결하려고 했습니다. 하지만 이렇게 범위 밖의 이슈를 리뷰와 같이 해결하게 되면 리뷰에 소요되는 시간이 길어졌고, 이로 인해 리뷰의 부담이 늘어났을 뿐만 아니라 관련 히스토리가 뒤섞여서 나중에 찾아보기 어렵게 되는 문제가 있었습니다.

이와 같은 문제를 피하기 위해서 리뷰 범위 밖의 문제라고 판단되는 경우 우선 이슈 트래커에 기록을 해두고 리뷰 이후에 해결하는 것이 더 바람직한 것 같습니다.

리뷰 중 잘 모르겠거나 고민되는 부분을 발견했을 때 대처하기

아직 제 경험이 충분하지 못하기 때문에 코드 리뷰 중에 파악하기 힘든 부분, 혹은 더 좋은 구조나 구현에 대해서 고민이 되는 부분이 있을 때가 많았습니다. 이럴 때는 혼자서 고민하기보다는 코드 작성자에게 질문을 하고 의견을 교환하는 것이 좋은 결론을 내리는 데 더 도움이 되었습니다.

한편 작성자의 의도가 불분명할 때 ‘괜히 물어보면 지나치게 간섭하는 것이 아닐지?’ 고민이 될 때가 있었는데요, 그런 걱정 때문에 궁금한 점을 넘겨버리는 것보다는 질문을 하는 것이 결과적으로 더 좋았습니다.


상호 간의 감정을 배려하며 표현하기

아무리 좋은 도구를 사용하고 명확한 프로세스를 가지고 리뷰를 하더라도, 소통의 과정에서 감정이 상하는 일이 발생한다면 코드 리뷰 자체가 거북한 과정이 되어버리기 쉽다는 생각이 들었습니다. 서로 불편해져서 아무 말도 하지 않게되면 리뷰의 결과에도 좋지 않은 영향을 미치게 될 것입니다.

리뷰어의 입장에서는, 어떤 표현을 하기 전에 항상 ‘작성자가 나름의 최선을 다해서 작성한 코드를 비평하고 있다’는 점을 유념해야합니다. 특히 작성자가 해당 플랫폼을 처음 다뤄보거나, 프로젝트에 참여한 지 얼마 지나지 않았거나 해서 코드에 대한 이해가 부족하기 쉬운 상황이라면 더욱 그렇습니다.

반대로 리뷰를 받는 입장에서는, 리뷰어의 코멘트를 그저 귀찮거나 달갑지 않은 비난이 아니라 더 나은 코드를 위한 바람직한 의견으로서 받아들이려고 노력해야 합니다.

어느 입장에서든지 자신의 주장을 펼칠 때는 주관적인 근거보다는 객관적이고 구체적인 근거를 들어서 이야기하는 것이 매우 중요하다고 느꼈습니다.