회사 프로젝트에서 TDD 실천하기
2018년 6월의 글이다.
글의 말미에 "약 1년간 TDD를 공부해왔는데, 무엇보다 현업 프로젝트에 TDD를 도입하게 되었던 것이 가장 큰 수확이다. 개인 프로젝트에서 많이 연습한 내용을 바탕으로 이제 현업 프로젝트에서 TDD를 수행할 텐데, 이 과정에서 얻을 수 있는 것들이 어떤 것들이 있었는지, 회고할 날을 기대해 본다." 이렇게 언급했었다.
약 3년이 지난 지금 이렇게 회고할 수 있게 되어 나 자신과의 약속을 지킨 것 같아 기분이 좋다. 나는 TDD를 지속하고 있으며 부족한 부분에 대해 지금까지도 연습하고 또 연습한다.
글을 작성할 때 즈음부터 회사 프로젝트에서 모듈화 하는 과정에서 서브 프로젝트를 생성해서 TDD를 연습했었다. 그리고 앱에도 일부 테스트 가능한 설계 영역에서는 테스트를 적용하고 연습했다. 이때는 팀에 혼자만 있던 때였다.
2019년 10월 신규 프로젝트를 시작하게 되면서 TDD를 처음부터 할 수 있는 좋은 기회가 생겼다. 당시 팀원은 갓 입사한 두 명의 개발자가 있었고 이 둘에게 TDD에 대해 조금씩 전파를 하던 중이었다. 이후 팀이 빌딩 되고 10명이 되는 순간까지 나는 TDD를 지속했다.
이 글은 약 1년 반 동안 회사 프로젝트 진행할 때 TDD를 했던 그 과정에 대한 회고다.
결과부터 이야기하자면 앞서 얘기한 것처럼 나는 TDD를 지속했고 팀에는 테스트 코드 작성 문화가 정착되었다. 약 4천 개의 테스트 코드가 생성되었고 자동화된 테스트를 구축하고 CI pipeline을 통해 코드가 병합될 수 있는 체계가 갖춰졌다.
물론 이 과정까지 어려움이 없었던 것은 아니다. 처음부터 여기까지 구성하면서 어떤 어려움이 있었고, 어떤 시도들을 해왔는지 정리해보겠다.
먼저 TDD에 대한 이야기를 하지 않을 수가 없겠다.
TDD를 다 같이 실천하고자 처음에 시도한 방법은 먼저 TDD에 대한 지식 전파였다. TDD 강의를 준비하고 내부 인원들과 새롭게 채용되는 개발자들에게 TDD를 소개하고 어떻게 가능한지, 어떤 이점이 있는지에 대해 설명했다. 필요한때에는 페어 프로그래밍을 요청하거나 혹은 요청받기도 하면서 TDD 과정을 같이 진행했다. 하지만 결과는 내 생각과는 많이 달랐다.
현실은 만만치 않았다.
먼저 오래된 습관을 버리고 새로운 습관을 만들어 내는 건 어렵고 누군가가 그 방법과 이점을 알려준다고 해서 되는 것이 아니다. 스스로 필요로 한 상태가 아니라면 할 수 없다.
일단 합류했던 대부분의 개발자들은 테스트 자체가 생소한, 테스트를 작성해보지 않은 사람들이 더 많았다. 테스트 코드를 작성하는 것만으로도 일단 러닝 커브가 있고, 익숙지 않은 과정이며, 그 가치에 대해 아직 느껴보지 않은 상태이기 때문에 동기부여도 잘 되지 않았을 것 같다.
개발을 오랫동안 한 사람일수록 이 과정이 더 힘들고 어려웠던 것 같다.
오래된 습관을 버리는 것. 그리고 새로운 습관을 익히는 것.
내가 먼저 많은 테스트 코드를 작성하고 작성 팁 등을 코드로 직접 보여주려 했고, 이 과정에서 계속 나은 방향을 고민하면서 시도했다. 이 과정에서 가장 힘이 된 건 주니어 개발자들이었다. 테스트 코드를 작성하는 데에 많이 노력하고 그 가치를 알고자 각자가 노력했던 것들이 보였고, 시니어 개발자들에게도 이것들이 영향을 준 것 같다. 결과적으로 팀에서 "테스트 코드 작성 단계" 자체는 정착한 것 같다.
하지만 모두가 TDD를 하지는 못했는데 녹녹치 않은 현실적인 문제도 있었다. 테스트 코드를 작성하고 프로젝트 요구사항을 충족시키는 것까지는 어찌어찌 워킹할 수 있었으나 TDD는 습관을 완전히 바꾸지 않으면 불가능하다.
이걸 바꿀 수 있다고 생각했던 건 오만한 생각이었던 것 같다. 나는 이러한 능력이 없다.
그래도 팀 단위 TDD를 할 수 있는 방법에 대해서는 앞으로도 고민하고 시도해볼 생각이다. 예전에도 그랬지만 내가 먼저 많이 하고 보여주는 것이 지금 할 수 있는 최선의 시도일 것 같다.
모든 코드가 테스트되도록 하는 것이 당연히 좋겠지만 그건 팀이 이미 테스트 문화가 매우 잘 정착되어있을 경우에만 시도 가능하다고 생각한다.
MVVM으로 애플리케이션 설계 방향을 잡았고, 테스트 범위는 모델과 뷰 모델로 한정시켰다.
UI 테스트는 필요할 때에만 일부 작성하도록 했다. 신규 프로젝트인데 UI 테스트까지 했다면 매우 빈번하게 테스트의 변경이 필요하거나 작성된 테스트가 깨지는 상황들이 발생했을 것이다.
초기에는 테스트 자동화가 필요하지 않았다. 사람이 별로 없을 때에는 프로젝트 빌드 시간도 짧고, 로컬에서 테스트를 수행하는 것도 시간이 오래 걸리지 않았다. PR을 올릴 때에 이미 테스트 코드를 작성한 상태에서 확인하고 올렸기 때문에 이 과정이 수동일지언정 코드 병합에 안정감이 있었다.
하지만 사람들이 많아지면 자동화 테스트가 필요하다고 생각했고 실수로 깨진 상태의 코드를 PR 올리는 것도 막을 수 있어야 된다고 생각했다. 프로젝트 구성 초기부터 자동화 테스트를 위해 Circle CI , Bitrise, Travis 등 여러 서비스를 시도해봤다. Circle CI를 사용하면 좋겠다고 생각했는데 웬걸... PR에 트리거 되지 않는다니..
Circle CI 관련 내용이다.
여러 서비스를 비교해보던 중 마침 Github actions 가 서비스 되기 시작했고 사용해보니 원하는 것들을 얻을 수 있고 private git repo에서 일정 부분은 무료였기에 github actions로 구성하게 됐다.
CI / CD에 대한 개념도 경험도 없었던 지라 처음에는 workflow 만드는 것 자체게 힘든 과정이었다.
사실 처음에는 자동화된 테스트가 CI의 전부인 줄 알았었다.
결과적으로 만들어진 CI / CD 파이프라인은 아래와 같다.
처음부터 이렇게 구성하고 지속한 것은 아니고 테스트 자동화부터 시작해서 PR 룰, 브렌치 전략과 함께 코드 통합 룰을 만들고 이 과정을 다시 CI에 적용하는 등등의 과정들을 거치면서 정착된 workflow 다.
구성하면서 힘들었던 점
사실 위 그림을 보면 괜찮은 결과라고 보이지만 이 과정을 만들어 갈 때에 굉장히 힘들었다. 우선 CI를 통해 얻을 수 있는 것들에 대해 경험해보지 않았기에 논리적으로만 이점에 대해 이해했기에 확신이 없었던 것이 가장 힘들었다.
어떤 workflow 가 효율적으로 내가 원하는 시간을 줄여주고 개발에 안정감을 높일 수 있는지 전혀 모르는 상황에서 고치고 또 고쳐나갔다.
이 과정은 내 개인 시간에 했는데 ( 회사 업무시간에 하지 않았다. ) 내가 확신이 없는 작업인데 회사에서 일하는 시간에 이것을 하는 게 옳지 않다고 생각했기 때문이다. 모든 업무를 끝내고 야근까지 하고 나서 새벽에, 또는 주말에 시간을 내서 이것저것 시도해봤다. 함께 하는 사람이 없어 외로웠고 잘 만들고 싶다는 생각 때문에 부담감도 많았다.
가까스로 만들고 정착되는 상태가 되고서도 중간중간 워크플로우가 깨지는 경우도 있는데 ( XCode 업데이트에 대응하지 못했더랄지 cli 빌드 쪽에 arm64 관련 문제가 생긴 더랄지 cocoapods 문제가 생긴다랄지... 등등 ) 문제를 해결하는 것도 내 몫이었다.
이외에도 많은 어려운 점이 있었다. (... 후... )
사실 누군가 CI / CD를 좋아하고 관심이 있었다면 그 사람에게 맡기고 의지했을 것 같다. 만들면서도 팀원들에겐 솔직하게 얘기했었다. " 전 사실 이 과정을 좋아하지 않아요. 힘들고 귀찮고 하기 싫어요. 그래도 이걸로 얻어지는 가치가 있고 제가 그걸 얻고 싶어서 하는 거예요. "
약 1년이 흐르는 동안 어떤 이득을 얻을 수 있었는지 단순하게 절약된 시간만을 정량적으로 통계를 내봤다.
workflow는 1회 수행에 10분가량
( 4개 테스트 타깃에 대해 테스트 케이스 클린 빌드 & 런 )
1년간 수행된 PR Workflow는 4294회
42940 분 (715시간)의 시간 절약
개발자에게 흐름이 끊기는 10분은 그냥 10분이 아니라, 원래의 일에 집중할 수 있는 시간도 소요되므로, 그 비용 감소로 얻어지는 가치는 더 높음
이외에도 CI 로 얻을수 있었던 개발 안정감은 하지 않았을때와 많은 차이가 있다고 생각한다.
이제는 이걸로 얻는 이득에 대해 체감하고 정량적으로 증명할 수 있는 자료도 모아졌다. 더 이상 고민하지 않고 실천할 수 있다. 물론 혼자 하는 것이 아니니까 팀이 다 같이 실천하는 것이 제일 중요하겠지만
다음글에서는 테스트 작성 팁과 좋은 테스트란 어떤 것인지 고민하게된 사례에 대해 이야기 해보려고 한다.
마침.