Q&A: Architecture and Architect

3월에 모 부트캠프 참가자들을 대상으로 “S/W 아키텍처(Architecture)“에 대한 특강을 진행했다. 강의 이후에 이런 저런 질문들이 있었다. 질문들이 과정에 참가한 분들만 궁금해하는 사항들이 아닐 것 같아서, 정리해서 기록으로 남겨볼려고 한다.

원하시는 인재상, 어떤 개발자를 원하시는지 궁금합니다.

이야기를 개발을 리드하는 입장에서, 특히 쏘카의 개발 방향 관점에서 이야기했기 때문에 자연스럽게 이 질문에 가장 관심이 많았던 것 같다. 사실 좋은 아키텍처를 완성하는 과정에서 사람이 빠질 수 없기 때문에 관련된 질문일수도.

성장하려는 개발자, 특히 그 성장을 지속 가능한 코드를 결과로 가져가기 위해 노력하는 개발자가 내가 관심을 두고 원하는 인재이다. 특히나 개발 경력 5~6년차 이하라면, 더더욱 이런 부분에서 목마름이 있고, 이를 채우기 위해 스스로 노력하는 사람이 가져야할 태도라고 본다. 개발 분야만큼 빠르게 변화하는 곳이 없다. 그럼에도 안변하는 것 하나는 “코드(Code, Coding)“라는 것이다. 점진적으로 “스스로의 성장”에서 “함께 성장”하는 단계로 본인의 관점이 서서히 바뀐다면, 이게 주니어에서 시니어로 넘어가는게 아닐까 싶다.

얼마나 주무시고 얼마나 일하시나요? 자기계발을 위해서는 얼마나 시간을 투자하시나요 궁금합니다ㅎㅎ

Reference를 삼고 싶어서 하신 질문이신 것 같긴한데… 쏘카의 생활을 기준으로 이야기하면 주중에는 대략 5 ~ 6시간 사이. 부족하지만 이건 주말에 일부 보충한다. 다행이 아직까지는 언능 출근해야지 라는 생각이 들기 때문에 아침에 과음한 다음 날이 아니면 아침 기상이 부담스럽지 않다.

쏘카 이직 후 1년 동안은 코드와 인프라 등을 직접 보지 않겠다고 결심했기 때문에 따로 자기 개발이라고 해봐야 책 읽는 정도. 대부분은 지하철을 오가는 2시간을 활용할려고 노력한다. 하루 평균 1시간 정도는 업무와 무관한 책을 읽는 것 같고, 주말에는 4시간 이상은 책을 읽으면서 보내는 듯 하다. 최근에 읽은 책은 총균쇠, 공정하다는 착각, Drive(7년전에 읽었는데 다시 곱씹는 중) 등이 있다. 업무 관련되서는 Monolith to Microservices를 읽고 있다.

최근 쏘카의 채용공고에 MSA를 다룬다고 되어 있었는데, 그럼 쏘카는 현재 MSA에서 EDA(Event Driven Architecture)로 변화하고 있나요?

현재의 쏘카는 Monolithic system과 Microservices가 혼재되어 있다. 꼭 개발이 아니더라도 한번 움직이기 시작하면 변화와 변경은 쉽지않다. 이제 10살을 넘어선 쏘카도 마찬가지. 현재 서비스의 지속성과 개발/업무 효율을 높이기 위한 아키텍처의 전환이 함께 이뤄지고 있다. 또 EDA로의 아키텍처 변화를 위해 준비하고 있다. 쏘카의 사업 모델과 안전을 중심한 운영 방식은 어찌보면 이런 이벤트 중심의 아키텍처를 적용하고 실행하기에 매우 적합하다. 그래서 더 안타깝기도 했지만.

적합하다고 이를 바로 실행할 수 있는건 아니다. 실행을 위한 준비가 필요하고, 아키텍처에 대한 구성원들의 이해도 함께 있어야 한다. 아무리 좋은 거라도 몸에 맞지 않으면 탈난다. 우선 서로 맞춰나가는 단계가 필요하다.

이런 단계들이 잘 진행된다면 그래도 2022년 올해안에는 EDA로의 첫발을 시작할 수 있지 않을까 기대하고 있긴 하다.

소프트웨어 아키텍트가 되기 위해서는 어떤 커리어 패쓰를 밟아야하나요??

단언컨데… 정해진 길은 없다고 보면 될 듯. 사실 아키텍트는 자격증 혹은 시험으로 인정받는 역할이 아니다. 어떤 사람이 아키텍트로 불리는 이유는 주변 동료들이 합당하게 그 역할을 하고 있고, 할만하다고 인정하기 때문이라서다. 이렇게 인정받는 사람들은 대체적으로 아래 역량들을 공통적으로 가지고 있다.

  • 개발역량 – 최고가 될 필요는 없지만, 최고가 되기 위한 노력이 뭔지는 알아야 한다.
  • 리딩, 코칭 – 사람을 알 수 있어야 하고, 사람을 맞는 방향으로 이끌 수 있어야 한다.
  • 문서화 능력 – 코드를 읽을 수 있는 사람은 제한적이다. 명확한 소통을 위해서는 문서가 필요하고 코드만큼 깔끔한 문서 작성 능력이 있어야 한다. 개발자는 코드로 이야기하지만 아키텍트는 문서로 이야기한다!
  • 경험 – 적어도 5~6년 정도의 실무 개발 경험이 있어야 합니다. Infrastructure, Backend, Frontend, Data Store 영역에서 다양한 기술들을 직접 사용해보고 장단점을 평할 수 있어야 한다.

취업전에 회사가 어떤 아키텍쳐를 사용하고있는지 알수있는 방법이 있을까요?

알기 쉬운 방법 가운데 하나는 회사의 조직 모델 혹은 어떤 식으로 일하는지를 확인해보길 바란다. 목적 지향 조직 형태라면 MSA 이상을 하고 있을 가능성이 높다. 그리고 Project를 중심으로 인원이 모였다가 헤쳐지는 형국이라면 좋은 아키텍처 방식을 따르는 것은??? 강한 물음표를 던져봄직하다.

개발자로써 좋은 커리어 패스를 밟으려면 어떻게 해야할까요?

먼저 좋은 개발 문화를 가진 회사에서 경험을 쌓으시길. 땅이 좋아야 잘 자랄 수 있는 것처럼 문화는 이런 바탕이라고 본다.

좋은 커리어 패스는 결국 잘 성장하는 방법일텐데. 성장을 위한 가장 좋은 방법은 좋은 동료들과 협업이다. 배울 것들도 당연 많겠지만 성장을 위한 좋은 자극을 받을 수 있기 때문이다. 하지만 좋은 동료가 있는지 없는지는 겪어보지 않고는 알 수 없다. 그래서 우선은 회사 혹은 팀의 개발 문화를 먼저 살펴 볼 필요가 있다.

성장을 통해 기여할 수 있는 기회를 찾으시기 바란다. 기술적인 성장은 실제 기능이 고객에게 전달되었는지, 즉 서비스화를 통해 인정된다. 인정은 결국 스스로의 자신감으로 투영된다. 그럼 자신감도 생기고, 자신의 역량의 가치에 대해서도 제대로 스스로 평가받을 수 있다. 아무리 많은 준비를 했다고 하더라도 서비스로써 고객에게 전달되지 못한 경험은 좋은 경험이랄 수 없다. 만들고 운영까지 해봐야 제대로 안다.

종종 스스로의 위치를 확인하기 위해서라도 면접은 1~2년에 한번은 봐두는 것은 좋다. 하지만 이직 후 3년안에 이직하지는 마시길. 이런 이력이 2회 이상 있는 경우에는 채용시 큰 마이너스가 된다. 개인적으로 경영 악화 이외 이유로 2년 미만 이직 경험이 있는 지원자는 선호하지 않으며, 1년 단위의 이직 경험이 있는 친구는 절대 뽑지 않는다.

MSA와 모놀리식 투트랙을 공부하는 것을 좋은 생각이 아니라고 하셨고 어찌보면 주니어, 취업 준비생 입장에서 MSA를 공부한다는 것이 지적 허영일 수 있다고 하셨는데, 백엔드 취준생이 쉽게 빠질 수 있는 지적 허영에는 어떤 것이 있을까요?

“DI와 IoC 개념에 기반해서 개발했다.” 와 같은 이야기를 신입 개발자분들한테 이야기를 종종 듣는다. Design Pattern의 몇가지를 물어봐도 곧잘 답을 합니다. 하지만 간단한 Class diagram을 그려봐라, Java Interface를 사용해서 코딩해보라고 하면 못합니다. 요런게 대표적으로 빠지기 쉬운 지적 허영이다. 스프링의 Annotation 좀 안다고 DI와 IoC를 제대로 이해하고 아는게 아닌데 말이다.

개념(Concept)을 코딩할 줄 모르면 이런 것이 개발의 허영이다. 말은 누구나 한다. 개발자는 말보다는 코드로 이야기할 수 있어야지 않겠나. 그렇다고 디자인 패턴이 중요하지 않다는 것은 아니다. 꼭 공부해두시길.

주니어 입장에서 MSA 프로젝트를 만들어보는 것이 도움이 될까요?(트래픽이 나오지 않아 필요하지 않더라도)

RESTful endpoint 2 ~3개 정도를 정하고, 이런 Microservice들을 3개 정도 혼자 구성해서 해보시는 것과 몇 명(한 3명?)이 하나씩 나눠서 해보는 것도 좋다. 부하는 JMeter와 같은 간단한 부하발생기를 활용하면 충분히 만들어낼 수 있다. 해보면 Monolith과 비교해보고, 성능 차이나 구현 차이도 실제로 느껴볼 수 있으니까.

하지만 이건 연습이라는거! 이거 해봤다고 MSA를 해봤다고 이력서나 자소서에 적진 말자. 이것도 대표적인 허영이다.

주니어 개발자에게 추천해주고 싶으신 책이 있으신가요??

  • Design Pattern
  • Extreme Programming Explained: Embrace Change

특히 Extreme Programming Explained는 꼭 읽어보길 권한다. 필독서!!! 참고로 이 두 권은 원서로 읽어야 한다. 두 권 모두 한글책과 영어책으로 봤는데, 한글 번역이 더 헷갈린다.

– 끝 –

 

조직이 결국 아키텍처를 좌우한다.

어플리케이션 수준부터 시스템 수준의 아키텍쳐에 대한 이런 저런 이야기를 계속 해왔다. 사실 이런 이야기들은 이론이다. 이론과 현실은 다른다. 다르다는 것을 인정하고, 현실에 맞춰 이론을 적용하는 것이 선수들이 해야할 일이다.

현실을 규정하는 것들 가운데 가장 큰 몫은 환경일 것이다. 그리고 그 환경 가운데 또한 가장 큰 몫은 바로 조직 모델이지 않을까 싶다. 다른 글에서 Monolithic과 Microservice 아키텍처에 대해 이야기를 했다. 이론에 치우친 분들이 왕왕 Monolithic은 악으로 규정하고, MSA를 뭔 성배마냥 찬양하는 경우가 왕왕있다.

이런 분들께 MSA를 이야기하기 전에, 다음 질문들을 생각해보길 권한다. 당신은? 혹은 당신 조직은 어떤가?

개발 단위가 책임과 역할에 맞게 나뉠 수 있는 규모가 되는지?

MSA는 작은 규모의 서비스들이 만들어진다. 그리고 익숙해지면 더 많이 만든다. 만들어지는 것까지는 좋긴한데 이를 감당할 수 있을 만큼 사람들이 있어야 한다. 사람은 없는데 쪼개는게 좋다고 무조건 쪼개다보면 전체 서비스 혹은 시스템이 뽀개진다. 혹은 사람이 뽀개질지도.

이런건 경험이다. 이미 경험해봤다.

자율에 따른 의사 결정을 실행하고 그 결과를 책임질 수 있는지?

서비스를 마이크로화한다는 것은 빠른 변경과 실행을 하겠다는 것이다. 이런 “빠름”은 몇 단계에 걸친 승인 프로세스에 의해서 일하겠다는 것이 아니다. 서비스를 담당하는 주체(개발 단위)가 자율적으로 결정하고, 이를 적용한 후 결과를 확인하겠다는 것이다. Autonomous하게 움직이고, Fast Feedback을 통해 지속적인 개선을 하겠다는 것이다. 변경을 반영하기 위해서 승인 사다리(Approval Ladder)를 오르락 내리락 하길 조직의 Leader가 원한다면…  괜히 욕먹는다.

권한을 위임할 수 있는 리더가 있어야 한다. 위임된 권한으로 실행 조직이 자율적으로 결정하고, 실행할 수 있어야 한다. 물론 책임도 져야 한다. 그리고 권한을 위임함으로써 유발되는 결과에 대해서도 리더는 책임져야 한다. 님들 책임이라고 하는 분들이 있는데… 이런 리더분이랑 일하시면 매우 피곤한다. 피곤함을 느끼시는 분들은 가장 마지막에 있는 링크 클릭 부탁!

반대로 스스로 의사결정 하나도 못하는 개발자들이 MSA하겠다는 경우가 왕왕있다. “나는 책임지지 못한다. 고로 결정 못(안)한다.” 이런 개발자라면 쓸데없는데 본인과 회사의 자원을 낭비하는 꼴이다. MSA가 Monolithic Architecture보다 돈이 더 든다. 시간낭비 돈낭비 안하는게 좋다.

오류를 어떻게 바라보는지?

SOA가 차세대 Architecture가 될 것 같은 분위기를 잡던 2000년대 초반만 하더라도 Distributed Architecture 환경에서도 Single Application에서 가능한 모든 것들이 실현될 것만 같았다. 하지만 결론은 안된다는 것이다. 그래서 SOAP의 시대는 갔고, RESTful의 시대가 도래했다. SOA의 결론 가운데 하나는 오류가 발생했을 때 Distributed 환경에서는 이를 Transactional하게 관리할 수 없다는 것.

MSA에서의 오류는 태생적이다. Error free한 코드를 작성하는 노력은 MSA와 맞지 않다. 되려 오류가 발생할 것이라는 사실을 인정하고, 발생한 오류를 빨리 찾을 수 있고, 가능하다면 이를 만회할 수 있는 방법을 준비하는 쪽이 정답에 가깝다.

 

만약 이 질문에 대한 여러분의 답은 어떤가? 충분히 양적으로 질적으로 준비되지 않았다면 아직 떄가 아니다. 이런 구조를 도입하는 것도 학습과 준비가 필요하다. 그것도 나만이 아니라 함께 일하는 동료들도 함께 말이다.

 

 

지사(Local Office)에서는 하고 싶어도 못해봤던 것을 본사(쏘카)에서 실현중이다. 모든 것이 완벽한 상태는 아니다.

하지만 고객 중심의 서비스를 개발할 수 있는 Architecture를 만들어내고, 또 이 Architecture를 실현시킬 조직을 만들 수 있다는 것이 행복하다. 올해에는 내가 직접 개발하지는 않지만, 다른 분들이 개발을 더 잘 할 수 있는 환경을 만들어주고, 이 분들이 더 재미있게 개발하는 모습을 볼 수 있을 것 같다.

2022년 연말에 이 과정을 복기해보는 것도 벌써부터 흥미진진할 것 같다.

흥미진진한 여정에 함께하실 분을 모십니다. 빠른 탑승을 부탁드려요~

– 끝 –

 

 

개발 모델: 프로젝트 조직 vs. 서비스 조직

시스템을 개발하는 방식에는 여러가지가 있을 수 있다. 가장 크게는 남이 개발해주는게 있고, 내가 개발하는게 있겠다. 우리나라에서 소위 SI(혹은 외주)라고 부르는 방식이 남이 개발해주는 방식이다. 이런 개발을 “프로젝트” 방식이라고 한다. 대체로 요구 사항과 기간을 개발사에게 전달한다. 물론 돈과 함께. 개발사는 최대한 맞춰 개발하고 그 결과를 전달한다. 물론 필요하면 설치와 운영에 필요한 사항까지 잘 마무리해야지. 그리고 남은 돈을 받는다! 돈을 받으면? 끝이지! 개발하는 사람의 책임은 여기서 끝난다. (물론 구질구질하게 붙잡고 늘어지는 경우가 매우 빈번하다는…)

 

내(회사)가 직접하는 시스템 개발 방법은 다른가?

내(회사)가 개발해서 내(회사)가 사용할 시스템을 만드는 개발 그 자체는 남이 만들든 내가 하든 비슷하다. 다름은 개발이 끝난 후 사용하고 고치기 시작할 때 생긴다.

자체적으로 개발할 진행할 때도 마찬가지로 남이 하는 프로젝트 방식을 쓸 수 있다. 이 방식은 앞서 언급한 바와 같이 “끝”이 있다. 끝나면 개발을 진행하던 사람들은 보통 흩어지고, 시스템은 운영 전담 조직이 맡는다. 운영 과정에서 생기는 자잘한 수정 사항들은 운영 선수들이 직접 고치기도 한다. 하지만 시간이 흐르고 자잘하지 않은 문제점들이 쌓이면? 결국 남들이 하듯이 “고도화” 프로젝트 후, “차세대” 프로젝트에 돌입한다. 대체로 새로운 선수들이 새로운 마음 가짐으로 “고도화” 혹은 “차세대”를 진행한다. Original 프로젝틀 진행했던 사람들이 참여할 수 있다면 운이 좋은 편이다.

현재 사용중이지만 과거에 끝나버린 프로젝트를 새로운 마음으로 다시 한다는 건 생각 이상의 비용을 요구한다. 혹자는 소스도 가지고 있고, 개발자도 있는데 그게 왜 문제인지 질문할지 모른다. 신이 내려주신 “망각”이라는 재능을 잊지 말자. 이외에도 개발하던 환경이 홀라당 날라가버렸을 수도 있다. 혹은 믿었던 소스가 알고보니 스파게티 짜장이었을 수도! 사실 이게 더 큰 비용 유발자일수도 있다. 끝내는데 급급한 경우가 많을수록 파스타/짜장면 잔치가 벌어질 가능성이 더 많으니까.

 

남이 아닌 내가 하는 방식은 그럼 뭘까?

개발하면서 운영하고, 운영하면서 또 개발하는 방식이다. “끝”없이 계속 개발하는 것이다.

개발이 끝없이 이어지는 경우에는 다른 관점이 필요하다. 어제 작성한 코드를 가지고 오늘 작업하고 내일 또 이어져야 한다. 결국 코드가 이뻐야 한다. 지속 가능하고 관리 가능한 코드를 뽑아야 한다. 마찬가지로 이번주에 고친 코드를 배포해야하고, 또 다른 개발이 이어져야 한다. 손쉽게 배포할 수 있는 환경이 있어야 한다. 분리된 독립적인 개발 환경을 사용할 수 있어야 하고, 또 손쉽게 개발 환경을 만들 수 있어야 한다. 나만 개발하는게 아니니까.

고치다보면 고장나기 쉽다. 어찌되든 실수는 피할 수 없다. 그리고 실수는… 비난하지 말자. 사람은 실수를 통해서 배우고, 성장한다. 그럼에도 서비스는 계속되어야 하는데… 가장 좋은 방법은 고장의 영향도를 최소화하는 것이다. 서비스 전체가 죽어버리는 것보다도 절반은 살아남는게 그나마 다행이지 않을까? 그래서 요즘 마이크로 서비스 아키텍처가 대세가 된게 아닐까 싶기도 한다. 잘게 쪼갠 협력 모델이면 그나마 장애의 영향 범위를 제한시킬 수 있으니까.

그럼 “끝”없는 개발은 언제 끝나는 거지? 마침표를 찍는 지점은 더 이상 이 기능(서비스)를 사람들(고객)이 찾지 않을 때다. 이 지점에서 서비스는 종료되고, 시스템은 폐기된다. 버뜨… 서비스는 없어지는 경우는 그닥 없다. 다만 마이크로한 기능이 사라질 뿐이지. 소위 현대적인 방법으로 시스템이 만들어졌다면, 없어지고 새로 태어나는게 일상 다반사여야 한다.

어떤게 더 좋은 모델일까?

사실 정답은 없다. 다만 서비스를 제공하는 회사/조직 안에 답이 있는 것 같다. 규모가 있고 결과론을 중시하는 조직 스타일이라면 프로젝트 방식이 적합한 개발 모델일 수 있다. 능력있는 개발 집단을 구성하고 수행해야할 프로젝트를 빠른 속도로 개발한다. 안정화 후 별도 팀이 이를 넘겨 받아 이후 운영한다. 능력자들로 구성된 강력한 개발 파워를 최대화할 수 있고, 적절한 운영 조직을 갖춘다면 안정된 체계를 완성할 수 있다.

그러나 도메인에 대한 지식을 개발자의 쌓을 수 없다는 치명적인 단점이 있다. 또 개발이 기획서 중심으로 나갈 수 밖에 없다. 개발하는 사람들이 그 도메인에 대해서 모르니 “상세한 과업 지시서“가 있어야 개발이 가능하다. 때문에 중간에 뭔가가 바뀌는 걸 극히 싫어할 뿐만 아니라 이런 경우가 발생하면 차세대 시스템용 기획서가 나와야 할지도 모른다. 능력자분들이 개발만을 특히 좋아하는 개발자들이라면, 되려 이 방식을 매우 선호할 수 있다. 이 방식에서 마이크로 서비스 아키텍쳐? 명확하다면 Monolithic이 답이 아닐까? 굳이 쪼갤 필요가…

서비스 방식의 개발은 그래서 소규모 조직에서 작게 시작해서 점진적으로 성장하는 환경에서 활용될 수 있다. 작은 조직에서 작은 규모로 개발을 시작한다. 고객의 피드백에 따라 빠르게 변화를 가져간다. 빠른 변화를 위해서 제품의 핵심을 명확히 한다. 각각의 구성 요소들을 개별적인 소규모 서비스로 정의하고 개발한다. 이래야 빠른 피벗(Pivot)을 위해 뭘 가져가고, 뭘 버릴지 빠르게 판단할 수 있기 때문이다.

문제가 없는 건 아니다. 이 방식도 많은 중복이 있다. 마이크로 서비스 구조라고 하더라도 각각이 독립적인 어플리케이션이 되야하기 때문에 Server, Application Framework, CI/CD 등등의 중복 투자가 필요하다. 이런 Redundancy를 관리하기 위한 Governance 조직도 필요하다. 그래야 어느 정도의 일관성이라는 것을 유지할 수 있으니까. 또한 잘게 쪼개져있다보니 서비스적으로 업무적으로 조율이 있어야 한다. 누가 어느 기능을 개발하지, 혹여라도 이미 다른 마이크로서비스에서 개발된 기능을 중복해서 개발하고 있는건 아닌지 역할에 따른 기능을 매번 확인하고 확인해야 한다. 개발자 입장에서 또 다른 문제는 하나의 도메인에 개발자가 종속된다는 것이다. 좀 다른 일좀 해보고 싶더라도 업무에 깊숙히 들어가있으면 빠져나갈 도리가 없는 경우가 왕왕 있다.

그래서 나는?

나한테 질문한다면 “고객/사용자“를 먼저 생각할 것이다. 그럼 서비스 중심 개발이 답이다. 고객과 사용성에 빠르게 반응할 수 있기 때문이다.

끝없는 단거리 경주를 언제까지 해야할지 모르지만, 사용자에게 사용자를 위한 서비스 시스템을 만든다면 이 방법이 정답이다!

– 끝 –

라이엇: 6년 3개월의 기록

말그대로 파란만장했던 시간이었던 것 같다. 즐거웠던 기억도 정말 치열했던 기억도 다양하다.

좀 더 업데이트를 하겠지만, 그래도 그 시간의 추억을 기록해둬야 잊지 않을것 같아 남겨둔다.

2015년

배운것도 많았고, 좋은 사람도 만났던 네이버 시절을 마무리하고 7월, 라이엇에 입사했다. 글로벌 회사는 어떻게 일할까 싶은 기대를 안고 첫출근.

구글이나 마이크로소프트와 같은 글로벌 회사에 대한 환상이 있었던 것 같다. 약간의 실망? 걍 한국 회사네?

그럼에도 즐겁게 라이엇 생활을 시작했다. 입사 후 두달 채 안됐는데, 오리엔테이션 비슷한 교육이 본사에 있고 당근 다녀와야한다고 하네! 오!!!! 미국 출장을 가긴 가는구나~ 난생 처음 미국행 비행기에 올랐고, 함께 가는 친구들과 “우리가 언제 미국 본사에 와 보겠나?” 라는 생각으로 교육 후에 돌아볼 만한 명소들을 돌아봤던 것 같다. 사실 교육이기 때문에 뭐 그닥 업무라는 건… 본사 구경도 잘 하고 LA 구경도 잘 했다. 뭐 언제 또 출장을 오겠어.

10월에 월챔 웹 사이트를 급하게 만들어야 한다고 요청이 들어왔다. 글로벌 사이트가 있는데, 왜 이걸 다시 만들어야할까? 상황을 보니 만들어야 했다. 웃픈 현실이라고 해야할까?

처음으로 미국 친구들과 일을 시작했다. 처음에는 메일로, 그러다가 행아웃 채팅으로. 매우 재미있었던 건 영어로 말하는 사람이 제한적인 거. 다들 똑똑한 사람들이고 영어도 배울만큼 배웠는데 본인들 입으로 이야기하는게 아니라 다른 사람들 입을 빌려 이야기할까? 신박하달까? 직접 이야기하겠다고 말하고 본사 친구들이랑 작업을 했다. 시차라는거 정말 블러커다. 몇일 걸리지 않을거라고 생각했던 작업을 마무리하는데 한달이 걸렸다!!! 설마 여기와서 밤을 새겠어 했지만 시차때문에 몇일을 밤샜던 것 같다.

이후에 올스타 웹까지 만들어야 한다고 해서, 출장 다녀오겠다고 했다. (한국에서 작업하는거 힘드니 출장가는게 좋을거라고 꼬득인 친구… 얼굴 본지 오래됐네.) 무려 혼자! 혼자 뱅기타고 혼자 호텔에서 잠자면서 본사 친구들과 2주 동안 작업했다. 행아웃으로 이야기할 때 “싸가지없는 놈”을 실물로 봤고, 오해였다는 걸 알았다. 친절하고 착한 친구였다. 더불어서 서너명 eSports Web 담당하는 개발자 친구들과 PO를 사귀었다. 2~3주 이렇게 있다면 말 그대로 친구가 된다. 이때 사귄 호주에서 온 여전히 좋은 친구도 있다.

2016년

기술 부채 갚아나가기

급한 작업을 일단락 후 왜 이런 작업을 반복해왔는지 고민했다. 한국만의 특성이 과도하게 반영된 한국의 계정 체계가 만악의 근원이었다. 하지만 이걸 당장 고칠 수 있는 상황은 아니니 우선 인증 시스템부터 센트럴 시스템과 맞추자라는 생각했다. 여기서 발견한 또 다른 만악의 근원. “.co.kr” 도메인. 한국적이지만 시스템적인 통합에는 확실한 걸림돌이다. 형식이 아니라 내용과 진심이 전달되는게 정답이다. 이 정답을 향해 가자!

사실 문제가 이것뿐이겠나? 한국 시스템의 문제도 있었지만, 한국 요구 사항을 본사 시스템도 받아들이기에 아직 준비가 안됐다. 뭐 별수 있나? 또 비행기탔다. 새로운 친구들도 사귀고 두어번 관련 출장 이후에 한국에서도 미국쪽 인증 시스템을 사용할 수 있게 됐다. 과정에서 어떻게 하면 한국에서 운영하는 계정 시스템을 본사 시스템과 통합할지 생각하기 시작했다.

출장 후 돌아와보니 얼떨결에 팀장이 됐다. 개발만 할려고 왔던 건데…

핵과 욕설의 시대

2015년부터 커뮤니티에서 이슈가 되던 핵과 욕설이 본격적으로 무대로 올라왔다. 물론 그 전부터 문제를 인지했고, 해결 방안들을 내부적으로 계속 고민해왔다. 이정도면 대응이 가능하다고 한국 오피스 내부에서 계획을 수립하고 준비를 시작했다. 다만 글로벌 시스템들이 이미 있는데 “왜 그렇게까지 할 필요가 있냐?” 라는 본사 각 영역의 담당자들의 반대가 있었다. 아무리 글로벌 회사라고 하지만 플레이어들이 플레이하는 방식은 다르다. 어찌보면 그게 문화라고 지금도 생각한다. 하지만 글로벌 서비스를 통해 해결해야한다라는 취지의 반대가 크게 발목을 잡았다.

한국팀에서 서비스를 개발한다고 하더라도 센트럴 팀의 도움을 받아야 한다. 불행히도 도움받아야 할 서비스에 대한 오너십(Ownership)은 센트럴 팀들에 있었다. 대응 가능한 한국 서비스를 만들어가는 과정에서 이 컨텍스트(Context)를 이해시킬려고 안되는 영어로 정말 많이 노력했다. 하지만 오너십은 정말 큰 허들이었다. 한국 서비스를 접목시키기만 하는데 그 과정이 정말 치열(처절)했다. 많은 사람들의 노력으로 완벽하진 않지만 한국 시스템이 준비됐지만, 여전히 하나의 서비스를 거스르는 한국 시스템에 대한 반대는 남아있었다.

한국 리더십에서 이 문제를 풀려고 몇번이나 태평양을 왕복했지만, 결론은 앞으로 나아가지 못하고 공회전 상태였다. 결국 한국 리더십에서 결정했다. 물론 준비에 대한 확신이 있었지만 믿기지는 않는 결정이었다. 대단했다!! 한국 서비스 시스템들을 턴온했다. “일해라 라이엇!“의 핵심인 서비스들이 릴리즈됐다. 반응은 말 그대로 대박이었고, 롤을 접었던 플레이어들이 다시 돌아오기 시작했다.

2017년

치열함 이후의 평온함. 2017년은 평안했던 것 같다.

센트럴 개발팀 방문!

치고박고 겁나 싸우던 본사 개발팀이 한국으로 온단다. 엥? 사업팀이나 PO가 아니라 개발자들이 온다구?

사실 한국 오피스를 셋업된 이후에 본사 개발자들이 한국팀과의 협업을 위해서 방문한 첫번째 사례였다. 더구나 온전히 한국팀이 개발한 서비스에 대한 지식을 얻고, 협업을 목적으로 온다고 하니. 개인적으로 매우 신났다! 오기전에 한국팀에 궁금한 점과 한국팀에서 협업하고 싶은 부분들을 정리했다.

정말 회의에서 서로 욕하기 직전까지 갔던 친구들이 드디어 사무실에 등장했다. 역시나 얼굴보고 이야기해보니 달랐다. 문화가 다르면 접근하는 방법도 달라야 한다는 부분에 공감대가 생겼다.  비로소 그 친구들도 왜 우리가 이렇게까지 서비스 개발에 매달렸는지, 왜 한국 서비스가 글로벌 서비스보다 더 잘 동작하는지 이해했다. 그리고 2주간에 걸쳐서 한국 사무실에서 함께 작업을 했다. 물론 쏘주는 덤이었다. ㅎㅎㅎ

서로가 서로에게 쌓인 오해를 풀게됐고, 이 친구들 가운데 베프도 하나 생겼다. 나중에 출장갔더니 얻어먹었다고, 본인들 회식 자리에 데꾸가서 신박한 LA 음식 먹을 기회도 줬다는… (하지만 나에게는 역시 한식이…)

로열티, 숙원 사업을 시작하다.

한국의 비지니스를 담당하는 큰 축 가운데 하나가 PC방 사업이었다. 초기에 사업을 진행하기 위해 센트럴 팀이 이 시스템을 만들었는데… 비지니스는 한국에서 하는데 서비스 개발은 센트럴 팀에서 진행하다보니 많은 어려움이 있었다. 소통도 문제고, 시차도 문제고. 플레이어분들도 고통이고 업주분들도 고통이고 서비스를 운영하는 우리도 고통이었다. 이 고통을 센트럴 팀에 전달하는 것도 또 고통!!!

대차게 이 서비스를 한국팀에서 오너십을 가지고 재개발하겠다고 선언했다. 관련 팀들에게 이 프로젝트의 진행을 알렸다. 센트럴에서도 이 서비스에 대한 이해가 부족했고, 계속 문제가 발생됐던 영역이었기 때문에 반겼다. 계륵이라고 생각되던 서비스였기 때문인지 모르겠지만 순조롭게 한국팀의 오너십을 인정했고, 개발 팀을 셋업하고 2년이 넘는 긴 여정이 시작됐다.

2018년

새로운 준비의 시대가 도래했다.

LCK 그리고 앱!

LCK 리그의 격변이 시작되는 시점이었다. 종로에 경기장도 만들기로 했고, 자체 방송을 하는 것으로 결정됐다. 그리고 이걸 데이터 서비스의 형태로 만들어보자! 앱으로!!

전사 과제로 결정이 됐고, 앱을 개발할 수 있는 역량있는 개발자들도 뽑고… 9개월쯤의 긴 여정끝에 Ice Boxing하는 것으로 결론. 가장 결정적인 이유는 앱에 대한 전사(글로벌) 정책이었다. 앱이 한창 흥하던 시절이었고, 사내에서도 서비스 앱을 만들자는 것이 붐이었던… Awesome! 이라는 이야기를 많이 듣긴했지만. 무분별한 앱 개발에 대해 새로운 정책이 생겼다. 사실 우리만 앱을 개발할려는 건 아니었으니까. 이 정책을 비껴갈 수는 없었다. 라이어터니까.

이 프로젝트를 진행하면서 느낀 또다른 시사점은 오너십이었다. 본사와 매번 이 오너십때문에 치고박고 했는데, 정작 우리 스스로에게 요구되는 오너십에 대한 고민은 적었던 것 같다.

일을 하는데 오너십이라는 것으로 뭘까? 스스로 재미있는 일을 한다는 것과 결과를 만들어내기 위해 주도적으로 하고, 한 일에 대한 책임을 온전히 감당하겠다는 자세… 많은 생각이 들게 만들었다.

이 프로젝트는 중단했지만 이후 다른 프로젝트에 개발된 기술/경험들이 요모조모 사용됐으니까 만족한다.

롤 그 다음 게임

슬금슬금 롤 다음 게임에 대한 이야기가 나왔다. 한국에서도 본격적으로 멀티게임 시대를 위한 준비를 시작했다.

멀티게임 시대를 위한 첫번째 여정은 이를 감당할 수 있는 조직 만들기. 명목적으로만 존재하던 팟(Pod)이라는 조직을 구체화하고, 역할을 명시했다. 팟은 서비스 조직으로 서비스 중심으로 팟이 서비스 담당과 유지보수를 주도적으로 수행한다. 서비스가 없어지기 전까지는.

다음으로 필요한 것들은 적폐청산! 소위 기술 부채라 불리는 것들을 없애는 것이다. 운영이 급격하게 돌아가다보니 이 부분을 안고 갈 수밖에는 없었다. 하지만 새로운 게임이 출시됐을 때 이 부채들이 발목을 잡았다. 나아갈려면 먼저 이것들을 치워버려야했다. 청산해야할 적폐들이 어떤 것들이 있는지 파악했다. 쌓인 부채가 어마어마하기 때문에 한번에 이 부채들을 털어버릴 수는 없었다. 부채를 점진적으로 갑아나갈 방법과 그 사이에 이자를 어떻게 낼지등도 함께 고민해야했다.

신규 게임이 출시된 이후까지 이 기술 적폐 청산이 마무리되지는 않았다. 하지만 부채를 부채로 인식하고 갚아나갈려고 하는 노력을 시작했다는 것이 중요하다. 당장 할 수 없다고 안하면 결국에 부채가 이자 포함해서 어마어마한 눈덩이라가되어 굴러온다.

2019년

롤 다음 게임이 구체화되었다. 한국에서 여러 게임들을 운영한다고 했을 때 필요한 것들. 이것들을 정리하고 개발할거라고 선언하고.

정말 부지런히 태평양을 오고갔다. 소위 Game Agnostic Service 체계로 만들고, 특정 게임에 대한 의존성을 최대한 없애기 위해 노력했다. 여전히 가장 큰 어려움은 한국이라는 지역의 플레이어들과 운영의 특성을 함께 협업해야할 게임팀을 비롯한 플랫폼 영역의 팀들에게 이해시키고, 협조를 끌어내는 것이다. 부단히 노력했고, 로열티 서비스와 Anti-Addiction Service, 한국말로 하면 셧다운제? 를 기존 서비스들을 대체해서 여러 게임에 하나의 플랫폼으로 적용하도록 개발시켰다. 계정도 롤 기반 계정에서 라이엇 계정으로 한국 환경에서 운영되도록 만들고…

와중에 좌충우돌하는 다른 지역 팀도 좀 도와주고. ㅎㅎ 우리도 바빠 죽겠는데, 다른 지역을 도와주는게 실화냐고 욕도 좀 먹었다. 하지만 한국팀의 존재감을 다른 팀들에게 톡톡하게 보여줬고, 고맙다는 이야기도 들었다. 그럼 된거지.

버라이어티했던 것 같다.

그리고 롤 다음의 첫번째 PC 게임, “레전드 오브 룬테라” 서비스 준비를 마쳤다.

2020년

2019년 말에 코로나라고 하는 신박한 병이 발병하더니 전 지구를 휩쓰는 전염병이 되었다. 2월말에 이 와중을 뚫고 마지막 출장을 다녀왔다. 한국에서 본격적인 PC방 서비스를 제공할 “발로란트”의 운영 환경 준비를 위해.

모든 준비를 마치고 한국에서 이제 제대로 RiotGameS가 되었다. S의 무게감이 엄청 무거웠고, 정말 열심히 준비했던 것 같다.

  • 1월 – 레젠드 오브 룬테라 베타 시작.
  • 4월 – 발로란트 베타 시작. 레전드 오브 룬테라 정식 및 모바일 시작.
  • 6월 – 발로란트 정식 서비스 및 PC방 서비스 시작.
  • 7월 – 와일드리프트

이제 남은 기술 부채 해소에 전력을 기울여서 Seamless service environment를 만들어야 할 때다.

해야만 하는 일을 하는 시대를 끝냈다. 이제 우리가 할 수 있는 일들은 뭘까를 고민할 시점이다.

2021년

게임을 넘어서 다음 여정의 방향은 어딜까? 한국팀이 가지고 있는 서비스들의 역량을 강화하는 것이었다. 지속적인 서비스를 한국 플레이어들에게 제공하기 위해서는 반드시 필요하다. 한국은 사업과 개발이 정말 굉장한 시너지를 내고 있는 팀이었다. 이런 시너지가 계속 이어지게 하기 위해서는 “역량”이 필요하다고 판단했다.

우리가 개발한 서비스들은 한국 환경이라는 목적을 가지고 처음 개발이 시작되었지만, 이제는 다른 곳에서도 이걸 활용할 수 있는 여지도 생겼다.

명분, 기회, 가능성…

여러 단어들이 있을 수 있겠지만, 나의 여정은 여기까지.

10월의 마지막 근무일에 나의 라이엇 여정은 막을 내렸다.

이제 남은 사람들의 몫이다.

 

 

팀이 몽고에서 상을 받았습니다.

팀에서 개발한 서비스들 가운데 대용량 트래픽을 처리하는 경우, Mongo DB를 Main Repository로 사용하고 있다. 국내에서 제공되는 모든 트래픽을 모두 처리하기 때문에 MySQL같은 RDB로는 이를 처리할 수 없고, NoSQL 몇 개를 평가한 다음에 결국 주력으로 Mongo DB를 사용했다….

하지만 Mongo를 전담하는 인원을 둘 수 없는 지경이라… 전문적으로 시간 투자를 해서 관리하고 튜닝할 수 있으면 좋겠지만 환경상 그럴 수 없다. 이 문제 때문에 본사에도 좀 물어보고 했지만 결국에 돌아온 답은 SaaS를 이용해라… 모아진 결론이 SaaS 방식으로 사용하는 것이라 AWS에서 제공하는 Mongo SaaS서비스인 Atlas를 작년부터 사용하기 시작했다.

전문적인 서비스를 받을 수 있어서 좋긴 했지만, 당연히 비쌌다.

문제점은 이쪽도 이정도로 큰 데이터를 다뤄본 경험이 그닥 없었던 것 같다. 이런 저런 문제가 Atlas에서도 발생했다. 한국 Mongo쪽에서 계약을 하긴 했지만, 호주쪽에서 지원해주는 친구들이 덕분에 고생을 좀 했다. 물론 우리도 이 문제 해결이 되야 했기 때문에 좀 더 고생을 하긴 했지만.

그럼에도 돈을 쓰면 개발자는 개발에 집중할 수 있는 시간적인 이득을 볼 수 있다.

그리고… 내부에서 얻은 문제점들을 공유하고 발표도 하고 했다. 별로 신경을 쓰지 않았는데, 공유한 케이스가 다른 Mongo DB사용자들에게 도움이 됐나부다.

이번 Mongo. Live 행사전에 사용자들을 통해 투표를 받았고, “Going Global Award“를 받았다!!

뜻밖의 수상이긴 했지만 많은 의미를 주는 상이었다. 오픈 소스 커뮤니티를 통해 팀에서 사용하는 Mongo의 사용 방법이 다른 개발자들에게도, 특히 한국을 넘어서 전세계에 있는 많은 개발자들에게 도움이 되고 있다는 사실이다. 코드로 기여를 하는 것도 한 방법이겠지만, 오픈 소스의 최적화와 사용 방법을 공유하는 것도 큰 기여다. 사용자들(주로 개발자들)의 같은 문제로 고민하는 시간을 크게 줄여줄 수 있으니 말이다.

기분 좋은 수상이었고, 최적화에 수고해준 테크 리드와 모든 팀원들에게 감사하다.

응답 코드

최근에는 개발에 대한 깊이있는 논의를 크게 할 기회가 없었다.

개발할 일은 많지만 사람이 없으니. 당장 내 코가 석자다. 사람들이 매니저 역할에 집중하라고 하지만, 그럼 님이 좀 개발해주던지!

https://www.inven.co.kr/board/black/3583/1001283

https://www.inven.co.kr/board/black/3583/1001283

최근에 석자 코 줄이기에 매진하다가 응답 코드를 이야기하는 대화에 참견할 기회가 있었다. 한동안 못해보던 색다른 경험이어서 그런지 각자의 투지도 있었던 것 같다. 상반된 두가지 견해가 충돌하는 상황이지만 각각이 가진 Pros & Cons가 있기에 함 적어본다.

1003 코드가 뭘 의미하는건가요?

이야기는 이렇게 시작했다.

 

파트너사 담당자: 파트너사에서 우리 시스템을 연동할 때 간간히 1003 응답 코드가 내려온다고 문의를 받았는데 이거 뭔 의미인가요?

개발자: 회원 API 서버 조회 결과가 없는 경우에 그 응답을 내려줍니다.

파트너사 담당자: 코드에 대해 전달이 안된 것 같은데 다른 코드도 있나요?

개발자: 1001은 참여 제한, 1002는 조건 불일치 입니다.

이 대화에서 내가 주목한 포인트는 “1003” 이라는 Custom 코드다. 어라? 왜 HTTP Status code를 사용하지 않았지?

이 포인트에서 대화가 이어진다.

 

: 이거 따로 코드를 정의하지 말고 HTTP Status code를 사용하는게 더 좋을 것 같네요.

개발자: API 서비스가 아니고, 서비스의 취지에 HTTP Status code가 부합하지 않습니다.

: 4XX 계열 코드에 보면 404, 409, 411 코드들이 맥락에 부합하는 것 같은데?

개발자: 세분화된 오류 코드를 제공해줘야 파트너사에서 최적화된 플레이어 동선(UX)를 제공할 수 있습니다.

: 상세한 오류 코드를 제공하는건 보안 측면에서 좋지 않습니다.

개발자: 기획 과정에서 이미 확정된 사항이고, 이를 지원할려면 세분화된 코드를 지원해야합니다.

: 필요한 부분에서 기획을 변경하는 것도 개발자가 해야할 일입니다.

 

마지막 “나”의 말은 무지 꼰대스럽다. 아마도 듣는 사람 입장에서는 불편했을 것 같다. ㅎㅎ

컬럼리스트가 말하는 ‘젋은 꼰대’ (https://www.dbblog.co.kr/1285)

개발자의 입장

별도의 최적화된 코드를 제공해줌으로써 파트너사가 개발한 서비스는 문제가 발생했을 때 문제점을 바로 파악할 수 있다.  파트너사에서 신경을 좀 더 쓴다면 코드와 1:1 대응되는 사람이 읽을 수 있는 메시지를 사용자에게 제공할 수 있다.

더구나 이 코드는 최종 사용자에게 최적화된 UX를 제공할 수 있는 기반이 된다. 사용자가 고생하는 혹은 막힌 문제를 정확하게 이야기해줄 수 있다. 입력의 문제라면 친절하게 어느 입력이 어떻게 문제인지를 지적해줄 수도 있다. 이 부분은 대부분의 기획자들이 원하는 바다. 기획자의 기획 의도를 충실히 지원하고 싶다면… HTTP Status Code와 같은 범용 코드로는 부족하다.

나의 입장

별도의 코드는 읽을 수 있는 문자 형태(Mnemonic)으로 파트너사에게 제공되지 않는다. 이 서비스에만 유효한 단순 숫자일 뿐. 결국 산출물(문서)로 작성하고 관리해야 한다. 반면 HTTP Status Code는 만국 공통어. 심지어 개발자가 아니더라도 이 숫자의 의미를 아는 사람들이 좀 된다. 굳이 엉뚱하게 쓰지 않는다면 문서도 만들 필요가 없다. 이미 알려진 의미대로 해석하면 될테니까.

문제점 파악은 최적화된 로그가 정답 아닐까? 특정 상황에 딱 떨어지는 오류 코드는 시스템을 비집고 들어올려는 해커들에게도 데이터와 로직의 특성을 알려주는 가이드북이다. 진단과 분석을 할려면, 필요한 정보를 안전한 곳에 남기고 안전하게 볼 수 있어야 한다.

UX의 최적화를 세분화와 상황별 텍스트 메시징으로 보는 것은 좀 아닌 것 같다. 이런 방식은 한 5년 10년전에 먹히던 방식이다. 예전에는 친철하게 노출해준 텍스트를 읽지 않는 사용자들이 잘못이라는 비난이 먹혔다. 하지만 우리가 살고 있는 시대는 모바일을 넘어 동영상과 VR시대다. 텍스트는 읽히지 않는다. 그나마 아이콘과 이모티콘 정도를 봐줄 뿐.

과정의 시대가 아니라 빠른 결과가 되려 더 중요한 것이 요즘이다. 친절히 과정을 설명해주는 것보다는 빠르게 진행할 수 있으면 최고다. 간단히 되면 되는거고, 안되면 안되는 것을 똑 부러지게 이야기해주는게 모두에게 좋은 요즘 시대다.

 

 

개발자 연봉이 올랐어요!

넥슨에서 쏘아올린 개발자 연봉인상이라는 공이 전체 업계에서 요동을 일으키고 있다. 분명 작년 말에 연봉 협상은 이미 끝났는데, 자고 났더니 연봉이 1,000 ~ 2,000이 급상승하는 마법같은 한해를 시작하신 분들이 많다. 개인적으로 한국 게임 업계는 높은 노동 강도에 비해 낮은 연봉으로 악명이 높았다. 오죽 게임쪽 개발자들의 꿈과 희망이 네이버나 카카오로 이직하는 것이라는 말이 나왔을까. 많은 분들이 이번 조치로 꿈을 이루기 위해 희생했던 각자의 연봉도 함께 찾는 시발점이 됐으면 좋겠다.

시작은 게임 업계에서 출발했지만, 이제 주류 기업들이 개발자 연봉 인상에 동참했다. 어느 분야든 마찬가지지만 숙련된 인력은 사실 많지 않다. 엔지니어링 부분, 특히 개발 분야의 숙련된 엔지니어는 경험만이 아니라 현재(대)의 기술을 사용할 수 있어야 한다. 때문에 연륜과 꾸준한 학습과 적용 능력을 갖춘 사람들이라고 본다. 당연히 이런 사람들의 분포는 정규 분포의 끝자락에 있겠지.

한쪽에서 이런 사람들을 땡기기 시작하면 결국 제로섬 게임이 되버린다. 개발과 코딩을 제대로 할 수 있고, 원하는 것(Business)를 이해하고 만들 줄 아는 사람과 함께해야지 일이 돌아간다. 특히나 코로나 이후로 촉발된 비대면 사회에서 해볼 수 있는 사업 기회는 온라인으로 시작해 오프라인으로 이어지는 모델이 주류다. 그만큼 시작점을 만들어줄 수 있는 사람들이 시대적으로 절실한 상황이다. 고무줄처럼 늘릴 수 있는게 아니라 정해진 파이 크기다.

나눌 크기의 파이가 아니니 결국 남의 것을 빼앗아 올 수 밖에 없다. 그리고 합법적으로 쟁취할 수 있는 가장 좋은 도구이자 무기는 “큰 보상“이다. 소프트웨어 개발자라고 하더라도 이 사람들이 어떤 도메인에 있는지에 따라 이미 처우가 달랐다. 보상의 불균형의 시대에서 더 많은 자원을 확보하기 위한 보상이 치솟고 있다. 자본주의 시대는 모두에게 동일한 평평한 운동장을 제공하지 않는다는 것을 안다. 그 운동장에서 열심히 달리고 있는 1인으로써 금전적인 높은 고지가 존재할 수 있다는 것 또한 새롭다. 하지만 뭔가 좀 불편하다.

엔지니어링 마인드

작년말부터 현재까지 개발자의 몸값은 말그대로 “금값”이다. 코로나와 함께 비대면/온텍트라는 새로운 시대가 열렸다. 새로운 시대는 새로운 기회다. 이 기회를 잡을려면 개발자가 필요하다. 금값이 될만하다.

자 그래서 개발자분들은 어떨까? 톡까놓고 이야기해서 지금이 기회다. 처우와 보상의 개선 찬스를 놓치고 싶은 사람은 없다. 더 좋은 처우를 제공해주고, 개발자라는 이력만 있으면 이직할 수 있다. 와중에 모셔가겠다는 곳이 줄을 선다. 맘에 들지 않는다면? 이곳에서의 연봉을 Stepping stone 삼아서 더 높은 보상을 제시하는 곳을 뛰어 오를 수 있다. 모든 건 협상이다!

개발자가 역량 혹은 능력으로 평가받기보다는 협상으로 평가받는 시절이 지금 시절이다. 좋은 개발 역량을 가진 사람보다는 현재의 시장은 개발을 할 수 있는 사람이면 “역량”은 충분하게 생각하는 듯 하다. 요즘 환경에서는 좋은 협상 능력이 좋은 개발과 성장에 대한 욕구보다는 훌륭한 개발자의 역량이지 않을까? 와중에 2년 혹은 3년 사이에 이직을 두번만 할 수 있다면 아마도 보상은 수직 상승할 것으로 기대한다.  2~3년 전의 역량과 능력은 동일한데 연봉이 두 배로 뛴 친구를 본적이 있다. 만나면 흥미로운 주식과 투자 이야기를 전해준다. 개발 이야기를 할라치면 그건 걍 하면 되는거 아니냐고 말한다. 음… 머… 그렇지.

 

닷컴 버블의 재현

국내 개발 환경은 2000년대 초반에 맞이한 닷컴 버블의 효과를 오래동안 겪었다. 물론 요즘 취업하시는 분들이 90년대 후반 세대가 있으니까 뭔 호랑이 담배물던 시절 이야기인지도 모르겠다. 세월이 참 빠르긴 하다.

재미있는건 오늘의 IT, 개발 활황기와 닷컴 버블의 시점이 아주 많이 닮아있다는 것이다. 당시에도 인터넷 광풍이었고, HTML로 웹 페이지만 만들 수 있어도 개발자로 인정받았다. 지금보면 웹 페이지 쪼가리 정도인데도 불구하고, 성공적인 투자를 이끌어낼 수 있는 아주 호시절이었다. 4 ~ 5년정도 대유행의 시절이 있었다. 많은 젊은이들이 IT의 장미빛 미래를 당시에 보았다. 너도나도 개발에 뛰어들었고, 대학에서도 유래없는 전산 관련 학과의 정원이 늘었고, 인재들의 지원이 있었다.

하지만 버블이었다는 것이 판명되었다. 수많던 스타트업들이 버블이 터지면서 사라졌다. 일로써 이 분야에서 일확천금을 노리던 사람들의 자리가 순식간에 사라졌다. 회사들과 개발자들은 생존을 위해 소위 막노동판인 SI 업계로 향할 수 밖에 없었고, 저가 수주 경쟁과 낮은 임금에 시달리게 되었다. 소위 “제대로 된 개발자가 없다!“는 말이 이 시점부터 나오기 시작했다. “제대로 된” 개발자들은 안정적인 직장을 향해 네이버와 다음(현 카카오)로 향했고, 그럼에도 꿈을 이루고 싶은 사람들은 자신이 원하는 곳에서 버텼다.

젊은이들의 꿈의 이상향이었던 IT는 더 이상 그들이 원하는 곳이 아니었다. 3D라는 단어가 이들 머리속에 각인되기 시작했고, 함께 대학, 대학원의 전산 관련 지망자들이 급격히 줄어들었다. 학교는 취업이라는 학생들의 당면한 문제 해결을 위해 기본보다는 응용에 초점을 맞춘 교육 과정을 제공했다. 문제가 문제를 야기하면서 결국 시장에서 “제대로 된” 개발자, 특히나 신입 개발자를 찾기가 더욱 어려워졌다. 도대체 Process와 Thread의 차이를 묻는 질문이 언제까지 유효한 면접 질문이 되어야 할지 궁금하다.

앱을 통한 새로운 기회가 나타나기 시작하면서 다시금 이 분야에도 서광이 비치기 시작했다. 하지만 이미 10년 가량의 시간이 흘러버렸다. 개인적으로는 다행이고 산업적으로는 불행이겠지만 대략 이 10년 동안 제대로 된 개발 기초 교육과 성장을 위한 기회를 제공받은 개발자를 찾기가 매우 어렵다. 2021년 현재의 나이로 보면 38 ~ 45세 사이 구간 정도? 하긴 한국의 개발 문화에서 이 나이에 개발한다고 하면 좀 이상하게 보긴 한다. 경력자 면접에서 TDD, Microservice architecture, RESTful 등을 질문하면 근본을 기대한 답을 못한다. 경험을 갖춘 시니어가 끌어줘야 하지만, 되려 이론으로 무장한 주니어에게 가름침을 받을 상황이다. 노땅이 무조건 잘해야 한다는 이야기는 아니니 오해말자.

이전 세대의 10년 공백은 버블과 함께 터져버린 기대, 밤샘을 강요하는 과도한 일정과 사람 갈아넣기, 정당하지 못한 대우 등등이 겹치면서 발생했다. 기존에 있던 사람들은 이 길을 포기하고 치킨집 창업의 길로 뛰어들었고, 사회 생활을 시작하기 위해 준비하는 학생들은 전산 전공을 기피했다. 똘똘하다면 당연히 의대와 한의대였다. 빈자리를 채워주는 사람이 없으니 존버모드가 가능했다. 정말 꿈만 같았던 40대 개발자의 모습을 현실에서 실현하고 있으니까. 물론 성장은 정체됐고, ActiveX에 기대긴 했지만 IT 강국에서 소프트웨어는 빈사 상태가 되고 반도체만 남았다.

현재의 시점에 갖는 우려는 개발할 줄 아는 사람, 즉 경력자만 찾는다는 것이다. 쉽게 이야기하면 신입을 뽑을 이유가 사라져버렸다. 빠르게 만들어서 치고 나가야 하는 시간 싸움에서 갓 대학 졸업한 사회 새내기를 가르칠 수 있겠는가? 보상은 경력자 위주로 돌아가고 그들의 리그가 되며 그 Pool에서 제로썸 게임이 이뤄진다. 그나마 큰 기업이라는 네이버와 카카오마저도 “코딩만 할 줄 알면 뽑는다!“는 구인 광고를 내며 저인망식으로 경력자만을 쓸어담았다. 물론 최근에 신입 사원을 다시 뽑겠다고 이야기를 하긴 했지만. 저인망식으로 경력 개발자들을 싹쓸이하는 모습이 훌륭한 모습이라 생각되진 않는다. 부디 이번에 새로 뽑는 새내기 개발자들을 잘 성장시켜줬으면 마음도 바래본다.

우려되는 모습은 새내기로 시작할 수 있는 제대로 된 회사들이 많지 않은 현실이다. 결국 전산 전공자들이 성장하면서 자신의 가치를 키울 수 있는 자리가 한정된 상황이다. 그 자리를 얻지 못한 친구들이 생길 것이고, 이런 모습은 후배들 혹은 Computing, Programming 분야에 대한 학생들의 의욕을 저하시킬 것이다. 다른 이유긴 하지만 몇 년의 시간 후에 새로운 피는 없어지고, 버티면 이기는 세상에 한번 더 오지 않을까 우려가 든다

요즘의 이 흐름이 버블때와 마찬가지로 일시적인 흐름일지 혹은 건강한 생태계로의 자연스러운 전환인지 알지 못한다. 시간이 이야기하주겠지. 지금의 30대 초반의 개발자가 10년 후 나랑 같은 생각을 하는 일은 없었으면 한다.

보상의 유리 경계

보상은 외부에서 봤을 때 사람을 평가하는 일종의 측정값이다. 두루 좋은 역량을 갖춘 개발자(혹은 엔지니어)도 역시 좋은 보상을 받는다. 아니 받아야 한다. 그럼 개발자들의 역량 분포는 어떻게 될까? 왜곡되지 않았다면 정규 분포를 따라갈 것이다. 경력과 개개인의 역량등을 두루 고려했을 때 이 분포 곡선을 따라가는 것이 어느 정도 합당해보인다.

그렇다면 보상은 어떨까? 당연히 능력이 뛰어난 인재는 그에 합당하는 보상이라는 대우를 받아야한다. 반대로 능력이 대비해서 비교되는 사람이라면 낮은 금액이 주어지는게 우리가 살고 있는 자본주의 논리다.

자 그렇다면 지금과 같은 개발자이 몸값이 금값인 현재는 어떤 모습일까? 분포와 보상 그래프를 겹쳐보면 딱 아래 그림과 같지 않을까?

능력에 따라 이뤄지던 합당이 보상의 그림은 아이러니하게 사라진다. 보상을 능력이라는 기준으로 환산해서 개발자 분포를 다시 보면 아래 그림과 같다.

소위 능력있는 개발자들이 모두 마지막 구간에 몰려있다. 경력직을 채용할 때 이전 회사에서 받는 그 사람의 연봉이 그 사람의 능력을 평가하는 측정값이 된다. 이정도 받는 사람은 이 정도의 능력이 되겠지!? 하지만 이렇게 또이또이 몰려있는 상황에서 정말 그 사람이 원하는 능력을 보여준다고 확신할 수 있을까? 기술 면접에서 잘 걸러주겠지? 글쎄다.

두번째 문제는 능력과 성과에 대한 보상이다. 성과와 의미있는 결과를 만들어낸 사람에게는 적절한 보상이 있어야 한다. 월급은 상시 비용(Cost!)이다. 회사는 계산에 능숙하고 상시 비용을 줄이길 원한다. 고로 회사의 총 보상은 월급과 인센티브가 적절한 조화를 추구한다.  조화로운 비율이 어찌됐던, 주는 쪽보다는 받는 쪽에게 연말 한방 인센티브는 보상 관점에서 매우 큰 의미를 갖는다. 많은 인센티브를 받기 원한다면? 성과가 좋을 것 같은 알짜 프로젝트를 고르자. 물론 그 중에서도 때깔나게 표나는 일을 해야한다. 물론 그 프로젝트에 참여하기 위해서는 좋은 인적 네트워크를 활용해야 한다. 인센티브 잘 받을려면 여의도 정치를 회사에서도 잘 해야한다.

웃프다.

자본의 불균형

현재 닥친 상황에 가장 난감한 분들은 이제 개발자들이 필요한 Business를 시작한 분들이 아닐까 싶다. 현실을 놓고 보면 같이 할 파트너 가운데 개발자가 반드시 있어야 한다. 없다면 낭패다. 요즘처럼 귀한 몸이 되버린 개발자분들 가운데 이 좋은 조건들을 포기하고 가시밭 길을 걷겠다는 분을 찾아야 하니까.

좋은 개발자를 못나가게 붙잡을 수 있는 회사는 자본이 있는 회사다. 줄만큼 돈이 있어야 하니까. 네이버, 카카오, 삼성? 아 쿠팡이랑 현대도 있겠구나. 결국 좋은 개발자를 많이 보유하고 사업적인 다양성과 유연함을 보여줄 수 있는 회사는 돈이 있는 회사다.

새로운 뭔가를 해볼 중소, 중견 기업들은 앞으로 새로운 아이디어에 도전해볼 기회조차 잡기 어려운 상황이 올 것이다. 온/오프 Mix가 앞으로 몇 년 사이의 주류 사업 모델인데, 온라인을 구현하지 못하면 결국 말짱 도루묵이다. 결국 팀을 만들 수 있겠지만, 좋은 팀으로 발전하는 건 더욱 힘든 도전일 것이다. 재원의 수준에 따라 결정된 팀은 결과와 성장의 균형보다 오직 “결과” 그 하나에 집중할 것이다. 슈퍼스타가 있다면 그 사람이 해결할 것이고, 없다면… 글쎄. 잘 모르겠다. ㅎㅎ

문화따위는!

자본주의를 살아가는 1인으로써 돈은 중요하다. 나를 포함한 모든 개발자에게도 마찬가지다. 개인으로 보자면 그렇지만 조직으로 봤을 때는 어떨까?

누구나 이야기하지만 혼자 만들 수 있는 Product 혹은 서비스는 없다. 결국 팀이고 협업이다. 건강한 조직의 협업이 그만큼 성과를 낼 수 있고, 그만큼 양질의 서비스를 만들어낸다고 믿는다. 그리고 이를 지탱해주는 것은 암묵적으로 “우리는 이렇게 일한다.” 라는 조직의 문화다. 소통하고 토론하고 결과를 만들어내기 위해 주장하고 양보하는 것이다. 그것이 문화다.

돈이라는 요인이 이 과정에 들어오게 되면 참으로 난감하다. 누구나 좋은 평가를 통해 좋은 보상을 받고 싶다. 이건 결국 이기적 동물인 인간의 본성을 드러낸다. 숨기고, 상대방을 꺽고, 너의 것은 틀렸다고 이야기한다. 이게 말이 되나 싶긴 하지만 인간은 이기적이다. 어떤 면에서 보면 동물보다 더 동물적이다. 보상을 위해 결국 결과를 만들어낸다. 과정이야 어떻든. 건강한 조직일까? 서로 경계하고 헐뜯는 사이에 만신창이로 병들어 있을 것이다.

개발자로서 정신적인 고통받지 않으면서 즐겁게 일하기 위해서, 은퇴 이후를 넘어서 개발로서 일할려면 좋은 문화의 회사에 있는게 좋다. 개인적으로. 물론 어느 정도 위험을 감수하고 주식 대박의 길을 가겠다면 그것도 물론 응원한다. 해볼만하다. 하지만 있는 문화까지 망가트리면서 보상을 추구하지는 않았으면 좋겠다.

 

이번 기회가 기울어진 운동장이 어느 정도는 자리를 잡는 기회가 되었으면 좋겠다. 포털, 게임, 그리고 SI 분야를 포함해 역할과 능력 그리고 노력에 부합하는 개발쪽의 보상 체계가 잡혔으면 한다. 그리고 닷컴 버블의 10년 공백이 제로썸 게임을 통해 되풀이되지 않길 바란다.

직장인인 개발자는 당연히 결과를 만들어내야 하고, 당연히 회사는 이걸 요구해야 한다. 다만 개인의 성장은 당연히 회사의 성장에게 큰 밑거름이 된다는 사실도 잊지 말았으면 좋겠다. 큰 회사와 작은 회사 각각에서 할 수 있는 영역이 있을 것이고, 그것들이 모여지면 좋은 개발자 사회를 만들어낼 수 있지 않을까 싶기도 하다.

– 끝 –

 

Updating AWS CodeDeploy agent

DNS 서버 설정 변경 때문에 프로세스들을 재실행시켜야 했다. 서비스 프로세스는 별 문제가 없는데, 구시대적인 Code Deploy 체계는 예외다. 이건 음… 마찬가지로 재실행시켜줘야 한다. 아니라면 ec2 instance를 rebooting 시키던가. 하는 김에 업데이트까지 해보자.


sudo service codedeploy-agent status
sudo service codedeploy-agent stop
sudo /opt/codedeploy-agent/bin/install auto
sudo service codedeploy-agent start
sudo service codedeploy-agent status

크게 이상이 없다면 stop하는데 약간 지연이 있고, 나머지 과정들은 후다닥~ 처리될 것이다.

당시에는 이것밖에 없어서 이걸 사용했지만, 쓸만한 것들이 AWS Seoul Region들에 들어오고나니 적폐가 되버렸다. 후다닥 적폐 청산을 해야하는데 말이다.

2021년의 계획 – 오바하지말자

“내년에는 뭘할까?”를 고민했던게 얼마 전인 것 같은데 벌써 그 내년의 2월 중순을 지나고 있다. 벌써 한달이나 훌쩍 지나갔네. 연말에는 새로운 기술적인 시도에 대한 꿈과 진취적(?!!!)인 프로젝트에 대한 구상도 있었다. 한달이 지나 전반적인 플래닝을 팀과 해보니 이것 또한 과하다… 라는 생각이 든다. 인간이 가진 욕심은 어쩔 수 없는가보다. 버리자고 했지만 제대로 버려지지 않는다. 원래 그런 인간이 바뀔리가 없지. ㅋㅋㅋ

팀들에는 1년 계획을 분기별로 세워달라고 요청했다. 어정쩡한 수의 구성원들이다보니 내가 다 챙길수도 없다. 다 챙길려고 딱 한번 시도해봤지만, 역시 되도 않는다는 것을 실증했다. 원래 팀의 크기는 정해져있는데 그걸 넘어서 뭔가를 할 수 있다고 생각하는 건 오바다. 쪼개고 나눠서 위임을 했다고 했다. 그럼에도 직접 챙겨야 하는 사람들이 10명 가까이다. 많다…

1년 단위 계획을 세우는게 의미가 있나? 음… 솔직히 1년 계획을 세워서 그대로 실행된다고 절대 믿지 않는다. 연초에 만든 1년 계획을 곧이 곧대로 실행하는 것도 맞는 건가? 이게 맞다면 정말 엄청난 예지력이다. 이런식이면 와 계획을 세우라고 했을까? 팀장이 팀원들에게 갑질한건가???

팀에 요청한 연간 단위 계획은 “마일스톤(Mileston)” 개념으로 수립해달라고 했다. 물론 알고 있다. “마일스톤”이라… 거창하다. 그 이상의 세부적인 계획은 당장 필요없다. 365일짜리 Gantt Chart를 그리는 부질없는 짓을 할 이유는 없다. 딱 4Q(작대기 4개)의 시간 공간에서 팀은, 우리는, 무엇을 원하는지를 알고 듣고 싶었다. 원하는 것과 필요한 것의 사이를 매꾸는 역할. 그거이 아마도 매니저의 역할 아닐까?

계획은 계획일 뿐이다. 그럼에도 계획은 필요하다. 그래야 우리가 향해할 방향으로 키를 잡을 수 있으니까. 우리는 “라이엇 코리아”라는 배가 성취할 목표를 향해 나아갈 Direction이 필요하다. 필요한 계획은 방향성만 제시하면 된다. 바람이 불고 비가 오는 상황에서 뭘 해야하는지 그 상황이 답해줄 것이다. 그 방향으로 “성취“하고 “성취” 할 것이고, 그리고 개인과 회사 모두가 원하는 목표에 도달할 수 있다. 언젠가는.

원하는 건 “성과“가 아니라 “성취“다.

“오바하지 말자!”

올해 팀에 강력하게 주문한 문구다. 작년에 많은 일들이 있었고, 어렵게 해쳐서 2021년을 맞았다. 아직도 어려운 시국이고, 몸과 마음을 회복했다! 말하기 어렵다. 아니 불가능하지 않을까?

때문에 나아감에 있어서 “성과”를 추구하기보다는 “성취”를 달성하길 희망한다. 작은 성취가 모여서 나의 자신감이 되고, 다시 이것들이 모여 조직/팀/회사에 보탬이 된다라는 순리를 믿는다.

– 끝 –

 

Test is always right.

Coding을 하면서 많은 것들을 고민하지만, 테스트만큼 고민스러운 것도 없다. 논리적으로 도움되고, 유지보수를 위해서라도 반드시 필요하다. 하지만 빨리 만들어서, 고쳐서 내보내야 한다는 심리적인 압박감이 강해지다보니 넘어가자. 바쁜데… 라는 합리성을 부여해버린다. 그래놓고 장애나면 급 후회를 하긴 하지. 언제나 그렇지만, 코딩/개발 단계의 시간보다 장애 대응하면서 보내는 시간이 훨씬 길다.

개발자의 입장에서 테스트는 반드시 필요하니 꼭 작성해두길 바란다. 한번 쓰고 버릴 일이 아니라면 말이다. 개인적으로 TDD 애찬론자이기도 하고, 테스트의 가치에 대해서도 백퍼 공감한다. 하지만 타협을 요구하는 현실이 당장의 우리의 현실인 것도 부정 못한다. 그 안에서 타협점을 찾아내고, 올바른 길로 개발자를 이끄는게 좋은 개발 리더가 아닐까 싶다.

글을 쓸려고 보면 사설이 길다. ㅋㅋ

Java coding을 하다보면 써야하는 테스팅 프레임웍이 JUnit이다. 이전 포스팅에서 5가 나왔다는 이야기를 했지만, 실제로 사용해보니 4보다는 확실한 버전업이 된 것 같다. 특히 Spring framework과 결합된 단위 테스트 속도를 확실히 보장할 수 있는 점이 체감되는 것 같다.

0. Performance

이전 JUnit에 비해서는 테스트 실행 성능이 좀 빨라진 느낌이다. 기분탓인가? 성능상에 영향을 미칠 수 있는 변경점은 Java8 이후부터 지원하는 Lambda가 보편적으로 구현에 사용됐고, 여러 라이브러리들로 쪼개져서 지금 내가 사용할려고 하는 테스트에 필요없는 모듈들을 런타임에 로딩하지 않는다는 정도? 뭐 이 두가지만 효과적으로 다뤄준다면 빨라진 걸 이해할만한 것 같기도 하다.

상세한 변경 점들에 대한 설명은 Major difference page에서 확인할 수 있다.

1. Enhanced unit testing in the spring-framework

확실히 스프링과의 통합은 JUnit4 보다는 개선된 것 같다. 특히 단위 테스트 측면에서. Spring project에서 테스트하다보면 내가 만드는 테스트가 Unit test인지 Integration test인지 헷갈린다. 특히나 실행시킬때보면. 겁나 느리다. 이렇게 느리면 단위 테스트 작성할 맘이 안생긴다. 걍 한방에 Integration Test로 검증하고 말지… 하지만 Integration Test는 상황 제어를 Mocking 가지고 하는게 아니기 때문에. 짜기 싫어지는 경우가 더 많아진다. (그러다가 걍 포기. ㅠㅠ)

JUnit5와 결합된 Spring-test에서는 이 부분을 완전 속시원히는 아니지만, 이전보다는 훨씬 더 개선된 형태로 사용법을 잡아줬다. 설정의 구태의연함이 있지만, 그럼에도 이제 Controller 수준에서도 Mocking을 활용한 단위 테스트를 제대로 작성할 수 있다.

@ExtendWith(SpringExtension.class)
@Slf4j
public class ValueV3ControllerUnitTest {
    @MockBean
    ValueService valueService;

    @InjectMocks
    ValueV3Controller controller;

    MockMvc mvc;

    @BeforeEach
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mvc = MockMvcBuilders.standaloneSetup(controller)
            .addFilter(new CharacterEncodingFilter(Charsets.UTF_8.name()))
            .build();
    }

    @Test
    public void shouldQueryByKeyContainFederatedInfo() throws Exception {
        // given
        final String givenKey = "1111-2222-3333-4444";
        final Value value = Account.builder()
            .key(givenKey)
            .identities(Arrays.asList(new String[] { "google" }))
            .build();

        given(valueService.value(givenKey))
            .willReturn(account);

        // when
        mvc.perform(get("/api/v3/value/" + givenKey))
            .andExpect(status().isOk())
            .andExpect(content().json(new Gson().toJson(value)));

        // then
        verify(accountService, times(1)).value(givenKey);
    }

JUnit4 기반의 spring-test의 경우에는 Controller 테스트를 실행할 때 테스트와 무관한 다른 초기화 모듈들(Filter 혹은 Configuration 객체들)이 실행되었다. 인간적으로 지금 코딩할 부분도 아닌 부분에 뭔가를 해줘야 하는 것도 좀 찜찜하다. 하지만 그것보다도 더 짜증났던 건 테스트 실행 시간이 5초 혹은 10초 이상 걸리는 경우가 생긴다. 특히 그 초기화 블럭에서 JPA와 같은 부분이 있다면 상당히 시간을 잡아드신다. 수정하고 빠르게 테스트를 돌려서 확인하고 싶은데 이렇게 시간 걸리는게 쌓이면 전체 단위 테스트를 돌리는데 5분 이상도 걸린다. (거의 10년 다되가지만, 네이버때 테스트 돌리는 시간이 5분 가까이 되서 빡돌뻔!)

여기 설정에서 핵심은 아마도 이 부분이지 않을까 싶다.

@BeforeEach
public void setup() {
    MockitoAnnotations.initMocks(this);
    mvc = MockMvcBuilders.standaloneSetup(controller)
        .addFilter(new CharacterEncodingFilter(Charsets.UTF_8.name()))
        .build();
}

Controller 자체를 standalone 방식으로 초기화하고, 동작중에 필요한 filter 부분도 선별적으로 추가할 수 있다. 실제 서비스에는 해당 필터가 들어가겠지만, 당장 테스트할 부분은 로직에 대한 부분이니 집중해서 테스트를 작성할 수 있다. 필터에 대한 테스트가 필요하다면 그 부분만 따로 단위 테스트를 작성하면 되니까.

2. Nested: grouping tests with a purpose

하나의 객체에 여러 책임과 역할을 부여하지 말자라는게 아마도 OOP 좀 해봤다라는 분들의 공통된 의견일 것이다. 하지만 객체는 객체다보니 외부와 상호 작용할 수 있는 2~3개의 Public Method 들은 필수다.

각 method의 구현을 진행하면서 계속 단위 테스트를 추가한다. 하나 구현을 완료하고, 다음꺼를 구현할 수 있다면 좋겠지만, 객체 상태라는게 한 메소드에 의해서만 좌우되는거는 아니니까. (그래서 역할을 명확하게 해서 객체당 메소드의 개수를 줄이는게 필요하다.) 구현하는 객체의 메소드야 그렇지만, 이에 대한 테스트는 뭔 죄냐? 객체의 상태 변경에 따라 methodA, methodB 에 대한 테스트가 한 테스트 클래스에 뒤죽박죽 섞인다.

예전에는 methodA에 대한 테스트 케이스가 여기저기 널려있는게 보기 싫어서 경우가 많아지는 경우에 아예 테스트 클래스 자체를 분리했었다. 사실 이것도 나쁜 대안은 아닌 것 같다. 단점은 테스트 대상 클래스를 초기화하는 과정이 중복되거나 뭔가 빠지는 부분이 생긴다는거. 이걸 극복할려면 대상 클래스를 초기화하는 Builder 혹은 Factory 클래스를 테스트 패키지쪽에 만들어줘야 한다. 이론적으로는 백퍼 맞는 이야기지만 흐름을 잃지않고 메인 로직의 개발을 이어가고 싶은 사람의 입장에서는 맥 끊어버리는 일이다.

@Test
public void shouldTwoIdentities_WhenDefaultValueAndFederatedIdentityExist() {
    // given
    DefaultIdentity identity = RiotIdentity.builder().defaultValue("default").build();
    givenAccount.setDefaultIdentity(identity);
    final List givenIdentities = Arrays.asList(new String[] { "google" });
    givenAccount.setFederatedIdentities(givenIdentities);

    // when
    final Account actualAccount = V3Factory.create(givenAccount);

    // then
    assertThat(actualAccount.getIdentities().size()).isEqualTo(2);
}

@Nested
@DisplayName("Flat Tests")
class FlatizeTest {
    @Test
    public void shouldMakeFieldsFlat_ForGovtFields() {
        // given

        // when

        // then
    }
    ...

“@Nest” annotation은 그 관점에서 한 테스트 클래스에서 여러 테스트들을 관심 그룹에 맞춰서 묶을 수 있는 기능을 제공한다. 테스트 대상 객체에 대한 초기화 부분도 물론 공유할 수 있을 뿐더러 하나의 상태 변경 요소가 다른 메소드의 동작에는 어떤 Break를 줄 수 있는지도 바로 확인할 수 있다. 깨지면 어느 부분이 어떻게 깨졌는지도 계층 트리를 통해서 직관적으로 확인할 수 있다는 건 덤이다.

근데 좀 get/set 하는 함수 좀 그만 만들었으면 좋겠다. 경력 10년 20년 다 되가는 분들도 이런 식의 naming을 하던데, 정말 안타깝다. 객체의 state change를 유발하는 동작을 일으키는 method일텐데, 그 동작이 set 혹은 get 이라는 동사로 시작하지는 100% 아닐텐데 말이다. 생각이라는게 싫은건지 아니면 영어로 된걸 읽어본지 한참이 지나서일 것이다.

3. DisplayName

Test method 이름을 어떻게 할지를 결정하지 못했다면 요 annotation을 활용하면 좋다. Super natural language를 이용해서 달아둘 수 있다. 물론 가급적 테스트 메소드 자체에 대해서 DisplayName을 다는 건 바보같은 짓이라고 생각한다. 개발자라면 당연히 테스트 메소드의 이름이 테스트 의미를 가지도록 해야 나중에 테스트를 수정하더라도 이름을 맞게 고칠테니까 말이다. 이건 테스트 메소드말고도 서비스단의 메소드 이름을 짓는 경우에도 마찬가지다.

하지만 이게 쓸모있는 경우는 위에서 이야기했던 “@Nest”와 같은 보조 도구들과 함께 사용할때다. Test Grouping을 하거나 정말 부가적인 설명이 필요한 경우에, 이를 설명하기 난해한 경우가 있다. 이 경우에 활용하면 뱅뱅 헷갈리지 않고 테스트를 읽거나 실행하는 사람이 그 결과를 해석하는데 헷갈리지 않을 것 같다.