2019년 11월에 개최한 회사 컨퍼런스 NHN FORWARD에서 프런트엔드에 대한 고민이나 궁금증을 해결할 수 있는 프런트엔드 상담소 를 운영했었다. 다양한 고민이 있었지만, 연차나 직책별로 궁금증과 고민거리들이 비슷하다는 것을 알 수 있었다. 명확하게 묘수를 알려줄 수 있는 트러블 슈팅부터 프런트 엔드 개발자가 가야할 방향까지 다양한 고민이 있었다.

상담소

(상담소 전경… 핸드폰 파는거 아니다)

상담 내용 중에 많은 비중을 차지한 것이 바로 개발 문화에 대한 고민이었다. 현재 꽤 괜찮은 개발 문화를 가진 팀에서 일하고 있다고 생각하고 그 과정을 함께 했었기 때문에 내담자들에게 경험을 토대로 답변을 해줄 수 있었다. 내담자가 처한 상황이 워낙 다양했기 때문에 같은 주제라도 내담자마다 조금씩 다른 방향으로 이야기가 진행되었는데 한가지는 명확하게 전달했다. 조직원이 적어도 두 명 이상이라면 코드 리뷰 부터 시작하라는 것이다.

이 글은 상담소에서 미처 다하지 못한, 코드 리뷰에 대한 조금 다른 나의 의견을 공유한다.

코드 리뷰의 또 다른 효능

우선 결론부터 말하자면 나는 코드 리뷰에는 알려진 효능외에 추가 효능이 있다고 생각한다. 알려진 효능은 검색하면 많이 나올 것이고 추가 효능은 아래와 같다.

  • 동등하게 의견을 내는 것에 대한 진입 장벽을 낮출 수 있다.
  • 팀 내에 숨겨진 다양한 문제점들을 드러나게 한다. (조직원들 간의 숨겨진 갈등도 드러날 수 있다)
  • 도입한 프레임웍이나 방법론의 결과물을 서로 검토해 더 나은 방법을 공유하고 문제를 같이 해결할 수 있게 한다.
  • 지속해서 조직의 개선점을 찾는 화두를 제공해준다.
  • 조직의 개선점을 찾고 같이 해결하는 선순환의 시작점이다.

아마 코드 리뷰에 익숙한 사람이라면 공감할만한 내용이라고 생각한다. 이제 왜 그렇게 생각하는지 그 이유를 설명하려고 한다.

내담자들의 고민

상담소 내담자들의 개발 문화에 대한 고민 대부분은 어떻게 하면 자신이 소속된 팀이나 회사에 테스트 혹은 코드 리뷰를 도입할 수 있는지에 대한 내용이었다. 여기에서 테스트는 어떤 형태든 테스트 코드를 작성해 테스트를 자동화하거나 TDD로 개발하는 것을 말한다. 내담자의 문제는 어떻게 잘 도입하느냐가 아니라 어떻게 조직원들의 반발 없이 도입하느냐였다. 도입을 원하는 쪽이 있으면 그것에 반대하는 세력(?)이 있다는 것이다. 각 세력은 조직장과 조직원인 경우도 있고 시니어와 주니어 혹은 고인물과 뉴비인 경우도 있었다.

요즘같이 코드 리뷰나 테스트에 대해 정보를 얻기 쉽고 좋은 사례를 접하기 쉬운 상황에서는 도무지 이해하기 힘든 상황이었다. 반대 하는 이유에 대해 물어봤다. 사실 양쪽 세력의 이야기를 다 들어봐야 정확하겠지만 우리편인(?) 내담자의 이야기를 정리해 보면 현실적인 생산성과 같은 양호한 이유도 있었고 그냥 하기 싫은 거구나 라고 느껴지는 상황이 많았다.

그리고 반대할 이유를 찾지 못한 반대 세력도 있다. 그래서 어쨌든 도입은 했지만 제대로 유지 되지 않고 흐지부지되는 경우도 있었다. 사실 제대로 유지하지 못 할 거면 안하느니만 못하다. 어쩔 수 없이 찬성했던 사람들이 흐지부지한 태도를 보이고 의도적으로 방해하고 그것이 성공한다면 앞으로 그 어떤 것이든 조직에 정착하기 힘들 것이다.

무엇이든 일단 조직에 도입하기로 했으면 모든 조직원이 적극적으로 참여해 조직에 잘 적용될 수 있도록 서로 고민해서 조율하고 변형해야 한다. 특히 테스트가 그렇다. 신뢰할 수 없는 테스트 케이스들은 전혀 쓸모없고 관리 비용만 드는 레거시이며 독중에 독이다. 그렇기에 팀이 신뢰할 수 있는 테스트란 어떤 것인가에 대해 그 대상과 방법을 끊임없이 서로 고민하고 개선해나가야 한다. 신뢰할 수 있는 테스트가 무엇인가에 대한 내용은 이 글에서 다루진 않지만 내가 테스트에 대한 내 생각을 갖을 수 있던 것도 조직원들과의 끊임없는 소통이 있었기에 가능했다고 생각한다. 이제 팀의 보편적인 노하우로 정리되어 예전처럼 테스트에 관해 이야기를 하진 않는다. 하지만 또 개선 포인트가 발견되면 또다시 지긋지긋하게 이야기할 것이다.

좋은 개발 문화?

좋은 문화라는 건 도대체 무엇일까? 조직이 좋은 문화를 갖고 있다는 것은 단순히 그 조직이 코드리뷰를 진행하고 있거나 테스트 코드를 작성한다는 것을 의미하는 것이 아니다. 어떤 방법론 혹은 어떤 기술이더라도 조직원들이 스스로 개발을 더 잘하기 위해 혹은 생산성을 높이기 위해 도입을 고려하고 도입을 했다면 팀에 맞는 방법을 고안해서 결국 팀에 맞는 방법을 찾아갈 수 있는지가 그 팀이 가진 문화가 좋고 나쁨을 판단하는 척도라고 생각한다.

결국 조직원들 한 사람 한 사람이 중요하다. 한 사람 한 사람이 중요하다는 것은 모두의 의견과 경험이 존중되어야 하고 조직원들 역시 그 직급이나 직책의 차이 없이 자신의 의견을 낼 수 있어야 한다. 자유로운 의사소통을 위해 회사나 팀에서 직급을 없애고 서로 동등하게 닉네임을 사용하는 경우가 많아졌다. 직급 없이 닉네임을 사용하는 것도 자연스럽게 동등한 의사소통으로 이어지는 좋은 방법이라고 생각한다. 하지만 본질은 자유로운 의사소통에 있다. 직급만 사라졌지 의사소통이 자유롭지 못하면 아무 의미가 없다. 시니어가 주니어의 의견을 동등하게 받아들이는 것보다 의외로 주니어가 시니어의 의견을 제대로 이해하고 받아드리는 게 더 힘든 경우가 많다. 서로 노력해야 한다.

직급에 상관없이 나의 의견이나 아이디어가 관철될 수 있고 개인의 의견으로 팀의 행동 양식이 지속해서 개선되고 실질적으로 개개인에게 도움이 된다면 또 다른 의견이나 아이디어로 이어진다. 계속 선순환을 한다. 이렇게 되면 두말할 것 없이 조직원들은 조직에 자부심과 애정을 느끼게 된다.

코드리뷰로 시작한다

팀의 자유로운 의사소통을 기반으로 팀의 체질이 개선되면 기술, 방법론 그 무엇이든 팀에 맞게 소화할 수 있다. 나는 개발팀의 의사소통을 개선하기 위해 제일 먼저 시작할 수 있는 것이 코드리뷰라고 생각한다. 문제가 이미 있다는 판단하에서도 개선될 수 있지만, 문제가 있는지 없는지를 판단하는 기능도 제공한다. 개선의 시작은 개선점의 도출일 것이다. 코드리뷰를 통해 개발자들은 서로의 코드를 리뷰하고 코드에 대해 의견을 교환한다. 그리고 그 의견은 다소 민감할 수 있다. 그건 리뷰를 하는 쪽이나 받는 쪽 모두 마찬가지다 조심스럽고 민감하다. 코드 리뷰를 통해 뭔가를 배웠다고 느낀다면 고무적일 것이고 코드 리뷰로 기분이 나빴다면 감정적일 수 있다. 하지만 이런 단편적이고 일시적일 수 있는 의견의 교환을 넘어 코드 리뷰는 개발자들이 서로 코드를 통해 합의하고 결론을 내고 서로 같은 지향점을 바라보게 만든다. 즉 조직원들의 합의로 팀의 잠정적인 최선의 의견을 도출한다. 이런 과정이 반복되고 팀의 습관이 되면 서서히 팀의 체질은 개선된다. 단순히 띄어쓰기를 하는지 마는지를 결정하는 것에서 효율적인 테스트란 무엇인가를 같이 고민하는 것으로 발전할 수 있다.

코드 리뷰를 사이좋게 할 필요는 없다. 애초에 서로의 사랑을 확인하려고 하는게 아니다. 오히려 따끔한 의견이나 대립하는 의견이 많을수록 당사자나 리뷰에 참여하는 사람들에게 도움이 된다. 개발자는 자신이 작성한 코드로 지적받는 것이 힘들 수 있다. 노력하는 개발자일수록 자신이 작성한 코드 하나하나에 사연이 담겨 있기 때문이다. 코드 리뷰를 통해 조직원들은 다른 사람의 의견이 나와 다를지라도 그 의견이 옳다면 받아들이는 연습을 해야 한다. 사람의 성격은 모두 다르기 때문에 개개인을 모두 맞출 수는 없다. 하지만 코드 리뷰 과정에서 발생하는 개인의 감정을 계속 무시할 수도 없다.

코드 리뷰가 성공적으로 이루어지기 위해서는 코드 리뷰 자체도 주기적으로 리뷰하며 옳고 그름을 따지고 규칙을 만들어야 한다. 이 과정에서 코드 리뷰 중에 의도치 않게 개인의 감정을 건드렸던 문제들도 다뤄야 한다. 예를 들어 논쟁이 과열되면 자리를 바꿔서 차 한잔과 함께 얼굴을 맞대고 이야기 한다든지 스크럼이나 조직 회의로 미뤄 조직원들과 함께 이야기해서 결정한다든지 말이다. 규칙이 정해지고 코드 리뷰에 일종의 분위기가 생기게 되면 개인의 성격을 넘어서는 조직의 성격이 생긴다.

조직의 성격은 좋을수도 있고 나쁠 수도 있다. 경력 개발자나 신입 개발자가 입사하고 시간이 흘러 조직에 적응하면 그 조직의 성격에 맞춰진다. 훌륭한 성격의 조직이라면 잘 적응할 것이다. 하지만 훌륭하지 않은 성격의 조직에서 역시 잘 적응할 것이다. 오히려 나쁜 건 더 빨리 적응하고 신속히 행동 양식을 맞춘다. 그래서 팀의 체질을 개선하고 좋은 성격을 만드는 노력이 중요하다.

FE개발랩의 사례

뜬구름 잡는 소리는 그만 늘어놓고 실제 우리 팀에서 코드 리뷰를 통해 문화가 개선된 사례를 소개해보겠다. 처음 코드 리뷰를 도입할 때였다. 이때는 서로 민감해지지 않게 조심하자 정도만 미리 정하고 무작정 시작했다. 막상 코드 리뷰를 시작해보니 중요한 로직이나 구조에 대한 이야기보다는 스타일이나 컨벤션에 대한 리뷰로 많은 시간을 잡아먹었다. 스타일에 대해 리뷰를 하면서 스타일에 대한 서로의 다른 의견들이 생기게 되었고 아무리 사소한 것이라도 논쟁이 발생하면 별도의 회의를 통해 가장 나은 방법이라고 생각되는 안을 선택해 컨벤션으로 만들었다. 이런 과정이 반복되면서 팀 컨벤션이 개선되고 탄탄해졌다.

우리 랩은 코드 리뷰를 통해 랩 내 컨벤션을 강화했다. 코드 컨벤션이 치밀하면 코드 가독성까지 높아지는 효과가 있다. 그럼 코드 리뷰가 더욱 수월해진다. 나는 이제 이 컨벤션에 너무 적응되어 이 코드를 내가 만든 건지 다른 사람이 만든 건지 헷갈릴 때도 있다. 간혹 어떤 이는 그렇게까지 디테일하게 스타일을 컨벤션으로 만들 필요가 있느냐 한다. 여기서 각자의 개성을 들먹이는 사람도 있다. 아니다. 코드는 알고리즘이나 구조 혹은 디자인 패턴을 얼마나 적절히 사용했냐만 중요한 게 아니다. 알고리즘이나 구조 혹은 디자인 패턴이 코드 리뷰를 통해 더 나은 것으로 개선되는 것과 같이 스타일 역시 더 나은 안을 선택하고 컨벤션으로 만들어 고민 없이 사용해야 한다. 코드 리뷰를 통해 의견이 A라는 방법과 B라는 방법으로 갈리게 된다면 가독성, 성능, 확장성 등을 고려해 팀의 컨벤션으로 만들어야 한다. A와 B가 비교의 여지 없이 동등하다면 결정을 하기 위해 다수결로 정하기라도 한다. 그게 무엇이든 동일한 문제를 팀에서 더 낫다고 결정한 한 가지 방법으로 고민 없이 선택하기 위해 코드 리뷰를 한다. 그런 케이스별 최선의 결정안이 많이 쌓일수록 팀의 생산성이 높아진다. 스타일도 예외가 아니다.

이어서 사례를 보강해보겠다. 컨벤션이 개선되고 확장되는 것까진 좋았는데 컨벤션이 많아지고 커버하는 영역이 넓어질수록 코드 리뷰가 더 힘들어졌다. 컨벤션에 어긋나는 코드들을 잡느라 코드 리뷰 시간의 대부분을 허비했다. 처음엔 이런 시간이 문제라고 생각하지 않고 서로의 사소한 실수를 잡아주는 것을 즐겼다(?). 하지만 코드 리뷰를 할 때 마다 매번 동일한 스타일 이슈들로 시간을 낭비하는 것이 반복되면서 점점 문제로 인식하게 되었고 결국 해결 방안을 모색하기 시작했다.

해결 방법은 간단했다. 정적분석 도구를 도입했다. 기존에는 특별히 정하지 않고 개별적으로 다양하게 사용했던 정적분석 도구를 ESLint로 모두 통일하고 반드시 써야 하는 것으로 결정했다. ESLint는 확장하기 편하고 다양한 룰이 있어 팀 컨벤션에 대응하기 좋았다. 기존 컨벤션을 적용한 ESLint 룰을 공유했지만 ESLint는 우리가 고려했던 컨벤션 이상의 룰을 갖고 있었다. ESLint를 적용하기로 한 이상 다른 룰들 역시 팀에 맞게 컨벤션으로 정해야 했다. 그래서 이런 룰들에 대응하는 팀 내 컨벤션을 정하고 ESLint 업데이트로 추가되고 변경되는 룰을 반영하기 위해 주기적으로 ESLint 컨벤션 대응 회의를 열어 모든 조직원의 합의하에 ESLint 룰을 적용하고 그것이 그대로 컨벤션이 되었다. 어쩌다 보니 사실상 이 회의가 팀의 컨벤션을 주기적으로 리뷰하고 개선하는 회의가 되었다. 우리 팀의 ESLint 룰은 조직원들이 모두 참여해서 모두의 의견을 반영한 민주적인 룰이다.

이후 비슷한 문제로 ESLint 만으로는 부족하다고 판단해 Prettier를 도입했고 이제는 코드 리뷰에서 스타일 관련 리뷰는 거의 볼 수 없다. 요즘은 ESLint와 Prettier는 너무 당연한것이지만 그 당시에는 아니었다. 사례는 최대한 디테일하고 명확한 것으로 선정했다. 가능하면 초반에 발생했던 이슈로 선정했다. 아직 코드 리뷰를 적용하지 않은 팀이라면 초반의 사례가 더 도움이 될 거라고 생각했다.

정리

조직원들이 서로 협의해 문제를 발견하고 해결하는 과정을 반복하면 조직 문화가 좋아질 수밖에 없다. 나는 그것의 시발점으로 코드 리뷰가 가장 효과적이라고 생각한다. 코드 리뷰를 통해 작은 문제부터 해결하는 것이다. 그런 활동들이 고무되는 가운데 팀에 좋은 문화가 자리 잡는다.

그렇다면 FE개발랩은 현재 최고의 문화를 향유하고 있느냐? 그렇다고는 말하진 않겠다. 다만 우리 랩은 랩 원들이 모두 합의해 최선이라고 생각하는 방법으로 개발을 하고 있고 최선이라고 생각하는 행동 양식을 취하고 있다. 현재로서의 최선이다. 이 방법들은 언젠가 또다시 누군가에 의해 개선점이 도출되고 다 같이 의논해 개선할 것이며 또 그 개선안이 더욱 효과적으로 반영될 수 있도록 공유하고 리뷰하며 조율할 것이다. 조직의 문화라는 것은 너무 광범위해 나 같은 일개 개발자가 좋다 나쁘다 확언할 수 있는 영역이 아니다. 적어도 우리 랩은 좋은 체질을 가진 성격 좋고 건강한 조직이라고 생각한다.

최근엔 랩 내 주니어 개발자가 제안하고 리딩해 TOAST UI 프로젝트에 Lerna를 적용하는 작업을 진행하고 있다. TOAST UI 모든 리포를 거의 다시 구성하는 수준의 대대적인 작업이다. (그래서 힘들다는 건 아니다………….) 본인이 리딩하면서 정리한 내용을 블로그에 공유했다. 그냥 자랑하고 싶어서 언급해봤다.

FE개발랩이 코드리뷰를 어떻게 하고 있는지 궁금하다면 지금 바로 확인할 수 있다. TOAST UI는 모든 프로젝트가 오픈소스이며 모든 작업 내용은 github을 통해 확인할 수 있다. 각 프로젝트 리포의 Pull Request 를 확인하기 바란다.