TDD 뉴비가 느낀 러닝 커브와 재미

johnwi·2022년 1월 25일
1
post-thumbnail
  • 주간회고 02. TDD 뉴비의 Full-stack(?) TDD 1편

👉 hashnode에서 보기

3줄 요약

  • 테스트 코드 뉴비로서 어디서부터 뭘 해야될 지 몰라 막막함을 느끼고, 파일럿 프로젝트 때의 안좋은 추억이 되살아났다
  • 단순히 툴 사용법이 아니라, 테스트 코드를 작성하는 원칙이 뭔지 좀더 공부하고 정리해보고 싶다
  • 많은 장점들이 있지만, 무엇보다 테스트 패스할 때의 소소한 즐거움이 제일 큰 장점인 듯


테스트 코드 앞에만 서면~ 나는 왜 작아지는가~

지금 보니, 약간 망했다는 얘기를 굉장히 구구절절 쓴 것 같다...

작년 수습기간 파일럿 프로젝트(investing.com 클론, 👉 파일럿 프로젝트 회고) 초반에 여러가지로 시간을 많이 날렸지만, 그중에서도 가장 허탕을 쳤던 것 중 하나는 TDD로 개발을 해본답시고 1주일을 날린 것이다

1년 반이라는 예상보다 길고 힘들었던 커리어 전환 기간을 거치고 취업한 상태여서 너무 신이 났었는지, 이것도 해보겠다 저것도 해보겠다 너무 욕심이 많았던 것 같기도 하다

Vue.js도 처음해보는데 TDD를 해보겠다하고, 데이터 업데이트를 실시간으로 해보겠다고 SSE를 도입하고, 몇번 써보지도 않은 MongoDB에 잘 맞지도 않는 TypeORM을 억지로 끼워넣느라 많지도 않은 시간을 삽질하는데 써버렸고, 결국 중간발표까지 요구사항 절반도 못하게 되는 대참사가 벌어졌다

그나마 SSE, TypeORM은 어떻게든 됐고, 아 이렇게 하는거 아니구나 하는 걸 깨닫기도 했지만, Frontend TDD는 결국 시간만 쓰고 혼란스러움만 남긴 채 접게 됐다


그렇게 약 5개월의 시간이 지나고, 차트 서버를 담당하게 되면서 모놀리식 구조에서 모노레포 구조로 바꾸고, 프레임워크를 Koa.js에서 Nest.js로 변경하는 대공사를 벌이게 된다

내가 바꾼 코드들이 제대로 동작하는지에 대해 수작업으로 확인하는 과정들이 반복됐고, 이 단순 반복 작업들이 너무 귀찮아지면서 자연스럽게 TDD에 대한 관심으로 흘러갔다

프로젝트 구조를 모노레포로 바꿀 당시에는 줌투자 2차 오픈 일정이 빡빡하게 돌아가던 중이라, 구조 변경하랴 맵차트 개발하랴 테스트 코드를 넣을 시간이 없었지만, 오픈 이후 조금 여유로워진 상황에서는 TDD 방식으로 프레임워크를 Nest.js로 변경할 수 있는 시간이 충분했다

리팩토링 관련 책들을 읽으면서 테스트 없는 리팩토링은 반쪽짜리 리팩토링이라는 걸 깨달았기 때문에, 이번에는 TDD를 제대로 해보면서 리팩토링을 하고싶다는 마음이 들었다

문제는, 다시 한번 마주한 테스트 코드를 어떻게 짜야하는가에 대한 막막함이었다


지금 당장 TDD 하고 싶은데, 뭘 어떻게 해야 할까..???

TDD는 요즘 개발자(?)라면 당연히(?) 하는 거기도 하고, 워낙 많은 테스트 관련 책과 강의, 블로그, 아티클들이 있기 때문에 공부를 한다면 충분히 할 수 있는 분야인 것 같다

하지만 당장 프로젝트에 적용해보려고 구글링해보면, 생각보다 볼만한 것들이 많지 않았던 것 같다

물론 JS 테스트 코드를 짜려고 하면 언제나 나오는 Jest 사용법 정도는, 정말 너무 많다 싶을 정도로 자료가 많다

이런 라이브러리나 툴 사용법은 필요할 때마다 그때그때 공식문서 위주로 찾아보고, StackOverflow 검색해보고, 그래도 뭔가 부족하다 싶으면 GitHub이나 SourceGraph, tabnine 오픈 소스 코드 검색으로 예제를 찾아보면 꽤 괜찮은 내용들이 많다

그러나 당장 프로젝트에 적용하기 위해 찾아보고 싶었던 주제는 이런 툴 사용법이 아닌, 단위 테스트에선 무엇을 어떻게 테스트해야 하는가, Controller를 테스트하는데 MockService는 왜 만들어야하나 등 원리원칙적인 내용들을 찾고 싶었다

파일럿 프로젝트 때 TDD에 실패했던 이유 중 하나는, 컴포넌트 단위 테스트에서 이벤트, api 요청 등 단위 테스트 범위를 벗어나는, e2e 테스트에서 해야 될 것들을 자꾸 하려고 했기 때문이다

다른 하나는 테스트를 할 때 테스트 대상이 아닌 나머지 로직과 데이터를 Mock으로 만들어 제공하는 의미를 알지 못했고, 모든 걸 다 Mock으로 만들어서 제공하면 당연히 성공할 수 밖에 없는거 아닌가 하는 의문 때문에, 테스트 코드를 구현하는 게 의미 없다는 생각이 들었기 때문이다

부족한 구글링 실력 탓도 있겠지만 원하는 결과는 찾기 어려웠고, 차라리 내가 좀더 공부하고 정리해서 공유하는게 낫겠다는 생각이 들었다

올해 안으로 가이드라인을 정리해서, GitBook 이나 간단한 웹으로 만들어 공유해 볼 예정이다


하지만 기왕 쓰는 김에.. 회사 팀원들, 블로그, 유튜브, 강의 등 여기저기서 주워들은 내용들, 그리고 직접 테스트 코드를 구현하며 깨닫게 된 아주 간단한 원칙은 이렇다

  • 모든 테스트는 주어진 상황/컨텍스트(given)에 대해 성공 조건(when)-성공 결과(then), 실패 조건(when)-실패 결과(then)를 테스트한다

  • 단위 테스트는 함수/클래스 내부 동작이 잘 동작하는지를 테스트하기 때문에, 당연히 나머지 외부에 대해서는 정상 동작한다고 가정한다

    • Mock 함수, 데이터를 잘 만들어야 하는 이유 👉 이 때문에 그다지 효율적이진 않을 수 있다
    • 새로운 기능 개발하는 경우엔, Mock 함수/데이터를 만들면서 인터페이스나 추상클래스를 만들수 있기 때문에 설계 측면에선 괜찮을 듯

  • e2e/통합 테스트는 내부 동작보다는 함수/클래스 등 전반적인 기능을 테스트할 수 있다
    • 말그대로 end-to-end, 사용자 input에 따른 output이 어떻게 나오는지를 테스트
    • 실제 데이터, api를 가지고 테스트할 수 있음; mock 데이터/함수도 당연히 사용 가능
    • 리팩토링 등 이미 구현된 기능에 대해 코드 변경이 있는 경우

10년 만에 느껴보는 수학 문제집 푸는 맛(?)

VSCode, IntelliJ 등 에디터에서 테스트 관련 설정을 하면, 굳이 테스트 관련 명령을 하지 않아도 알아서 코드 수정을 반영해 테스트를 실행해준다

테스트 코드의 장점은 누구나 알다시피, 코드 변경을 하더라도 기능이 잘 작동하는지를 빠르게 확인할 수 있다는 점이다

그것말고도 개인적으로 꽤 괜찮은 side-effect를 느낀 부분은 개발자로서 자기 효능감을 느낄 수 있다는 점이다

학창 시절 수학 문제집을 풀고 채점할 때, 동그라미가 하나씩 늘어날때마다 기분이 좋았던 기억이 있는데, 깔끔하게 통과한 테스트 결과를 보면 왠지 상쾌하고 기분이 좋아지는 듯 하다

개발은 공부하면 할수록 스스로 부족하다고 느낄 때도 많지만, 이렇게 사소하게나마 내가 만든 코드가 테스트를 통과했구나하는 즐거움을 주는 게 가장 큰 장점이 아닐까 생각이 든다

profile
가볍게 TIL 남기는 velog, 꾸준히 성장하는 개발자

0개의 댓글