컴퓨터 지식/서평(독후감)

[도서리뷰📘] TDD - 테스트 주도 개발

서상혁 2021. 5. 29. 00:55

테스트 주도 개발 (켄트 백)

TDD (테스트 주도 개발)

 

들어가며

인턴 근무하면서 멘토님께 멘토링 지원비로 이 책을 사고 싶다고 부탁을 드리고 읽게 된 책이다. 많은 책들 중에 이 책을 선택했던 이유는, 안정적인 개발을 하고싶어서였다. 애초에 내 성격부터가, 기억력이 안좋고 꼼꼼하지 못한 타입이라, 무언가 문제를 만들어놓고 해결하는 스타일이다. 코딩을 할 때도, 이런 성격이 작용을 하다 보니, 반복되는 잦은 실수들이 생겨났고, 이를 없애는 방법이 없을까? 하는 의문이 들곤 했다.

 '함께 자라기' 를 읽으면서 느꼈던 점 중에, 실수가 당장 그 순간에는 나쁜 결과를 가져와도, 길게 보면 결국 성장하는 데에는 도움이 된다는 것이었다. 그렇다면, 실수로부터 오는 불이익을 최소로하면서, 실수를 해결하는 방식으로 코딩을 하면 되지 않을까? 하는 생각을 하게 됐고, 테스트할 때는 실수 혹은 실패로부터 오는 불이익이 없다는 점이 떠올랐다. 테스트 하는 단계에서는 내 코드가 백번 천번 만번을 에러를 일으켜도 문제가 없다는 점이다.

 이러한 점에서 테스트 주도 개발이 내 성격상 단점을 어느정도 상쇄해줄 수 있을 것이라는 생각으로 자세히 공부해보고 싶었고, 이 책을 택하게 되었다. 😀

 

 

TDD?

 이제 책에 대한 얘기를 하자면, 사실 이 책은 TDD의 방법을 자세히 서술하고 예시를 통해 이 과정을 구체적으로 설명해주는 책이기보다는, TDD 의 방향성에 대해 알려주는 책이라는 느낌이 든다.

 

 첫번째 챕터에서는 화폐에 대한 기능 구현을 예시로 들면서, 객체지향을 바탕으로 한 TDD의 예시를 통해 TDD가 어떤 식으로 진행되는지를 설명해준다. 사실 이 부분을 쭉 읽으면서 느꼈던 점을 솔직히 말하자면, '보통 다 이런식으로 코딩하지 않나? 이게 뭐가 특별한 것이라고 이렇게 긴 시간을 할애하면서 설명하지?' 하는 생각이 들었다. TDD를 설명하기 위해서 꼭 필요한 부분은 아닌 것이라는 느낌이 들었고, 예시가 과하게 길다는 느낌을 받았다. 물론 내가 필자의 의도를 온전히 이해를 못해서 그런가 싶기도 하다. 그래도 이 챕터에서 주목할만한 점은, "필요한 기능을 목록화 -> 기능에 따른 테스트를 목록화 -> 코드 구현" 의 방식을 보여준다는 것이다. 그리고 이것은 코딩의 방향성을 엄격하게 제시해준다는 데에 있어서 매우 이점이라고 생각한다. 때로 코딩을 하다보면, 구현해야할 부분이 너무 많거나, 이런 저런 이슈가 꼬여서 갈피를 못잡고 회피하게 될 때가 있다. 그런데 이 책의 첫 번째 챕터에서 보여준 "필요한 기능을 목록화 -> 기능에 따른 테스트를 목록화 -> 코드 구현" 의 과정을 따른다면, 적어도 방향성 하나는 확실히 잡고, 목표 기능 위주의 안정화된 결과물이 나올 것이다.

 또 하나는 리팩토링의 중요성을 강조한다는 점이다.

1. 테스트를 작성한다.
2. 어떻게든 실행가능하게 만든다. ('이 책에서는 빨간 막대를 초록 막대로 바꾼다.' 라고 표현한다.)
3. 중복을 제거하고 올바르게 만든다. (리팩토링의 과정을 의미한다.)

 

 위의 과정이 일반적인 TDD의 개발 과정이라고 소개한다. 리팩토링의 중요성은, 개발자라면 누구나 공감할 것이다. TDD에서는 그 중요성이 배로 늘었고, 오히려 그 리팩토링에 TDD의 핵심이 있다고 생각한다. 내가 TDD 를 직접 체험해보면서 느꼈던 점은, Test코드에도 dependancy가 존재한다는 점이다. 테스트 코드는 메인 코드를 테스트하는 것이기 때문에, 어쩔 수 없이 코드를 수정했을 때, 해당 코드에 맞게 테스트도 수정해야하는 경우가 생긴다. 나는 이 책에서 강조하고 또 강조했던 '리팩토링 과정'이 이런 부분을 최소화 시켜주는 데에 의의가 있는 것이라고 생각한다. dependancy가 줄었다는 점은 곧 안정적인 코드라는 점과 일맥상통할 것이고, 좋은 코드를 만들어 줄 것이다.

 

 두 번째 챕터는 테스트코드를 작성할 수 있게끔 하는 테스트 프레임워크를 직접 만들어보는 과정을 소개한다. 이 역시도 기능 설계와 테스트, 리팩토링의 과정을 거친다. 테스트 코드의 테스트 코드를 작성하는 셈이다. 생각보다 테스트 프레임워크가 간단히 구현이 돼서 놀랐고, Test에 대해 갖고있던 딱딱한 생각들이 조금 줄어든 것 같다. 그리고 실제 테스트 프레임워크도 이런식으로 간단히 구현이 되어 있나 싶은 궁금증이 들어서 실제 내가 사용중인 js의 테스트 프레임워크 jest의 소스코드를 살펴봤는데 역시나 이렇게 간단하지는 않다...ㅎㅎ ╰(*°▽°*)╯. 그래도 jest 라는 테스트 프레임워크 역시 마찬가지로 수많은 테스트 코드를 바탕으로 작성되고 있다는 점이다.

 

 마지막 챕터는 여러 테스팅 패턴에 대해 소개한다. 각 패턴을 자세히 다루지는 않고, 이런게 있다는 식으로 짧은 분량으로만 간단하게 말하고 넘어간다. 그런데 여기서 쓰이는 용어들이 우리가 익숙하게 쓰는 말들이 아니라서 그런지 번역된 글을 읽어보면 바로바로 직관적으로 이해가 잘 되지 않는 느낌을 받았다. 이 부분은 꼭 다시 읽어봐야 할 것 같다. 그래도 부분부분 꿀팁을 받는 느낌이라 좋았고, 뒷부분에는 QnA 형식으로 궁금할 수 있는 부분들에 대해 예상 질문과 대답 형식으로 쓰여져 있어 이해하는 데에 좀 더 도움이 됐다.

 

이런저런 나의 생각들

 개인적으로 아쉬웠던 점은, 내가 궁금했었던 네트워크 관련 테스트, 데이터베이스 테스트 처럼 외부 의존성이 포함된 테스트 들에 대해서 어떻게 해나아가야할지는 이 책에서는 간단히 언급만하고 다루지 않기 때문에 그 부분에 대해서 다른 자료들도 찾아보고 고민을 많이 해봐야할 것 같다. 얼마전 본 toss 컨퍼런스에서는 TDD 100% 커버리지를 어떻게 달성했는지에 대해 소개해줬는데, 여기서는 책의 내용과 같은 TDD의 기본 내용보다는, 어떻게 테스트를 최적화해서, 최대한 빠르게 테스트가 끝나게 했는지에 대한 내용을 담고 있다. 프로젝트 전반에 걸쳐 1600개의 테스트가 있다면, 아무리 빠른 테스트들이라고 하더라도 빌드 전에 테스트 과정으로만 일반적으로는 1분이 걸린다는 뜻이고, 이는 비즈지스 민첩성을 매우 떨어트린다. 테스트의 단점일 수 있는 부분, 그리고 그 부분을 어떻게 보완해나아가야 할지에 대해 생각해볼 수 있었다. 또한, Mutation Testing이라는, 테스트 자체가 괜찮은지, 충분한 테스트 케이스를 포함하고 있는지에 대한 테스팅을 소개해준다. 테스트 코드의 인자값이나, 연산자들을 임의로 바꿔가면서 테스팅이 통과하는지를 자동으로 테스트해주는 기능인데, 아쉽게도 상당히 많은 연산을 필요로하는 작업이라 아직까지는 시간 문제로 활용이 되고 있지는 않다고 한다. 이 또한, 새로운 시선을 일깨워주는 좋은 사례였다.

 

 앞으로 내가 개발을 어떤 식으로 할지 고민해볼 수 있는 시간을 갖게하는 책이었다. 무조건 TDD가 답인 것은 아니다. 실무에서도, 테스트 없이 개발하는 분들이 많고, 테스트를 기반으로 작성된 코드라고 에러가 생기지 않는 것은 아니다. 하지만, 테스트코드가 안정된 코드를 만들어주는 것은 확신할 수 있다. 그리고 테스트를 작성하지 않는다고 하더라도, 필요한 기능목록을 작성하고, 그 기능 목록을 중심으로 하나씩 구현 및 리팩토링 하는 과정에 대한 맥락은 장기적으로 봤을 때, 코드의 질을 매우 늘려주는 것 같다. Test 코드를 작성하지 않더라도, 그 기능에 대한 테스트는 머릿속 과정에서라도 거쳐가야 한다는 교훈을 준 책이다. 앞으로 TDD가 습관화가 되어서 내 개발패턴에 자리잡기를 바라는 생각으로 조만간 한번 다시 읽어볼 생각이다.

728x90