본문 바로가기

TDD의 장점은 무엇일까?

한참 TDD를 공부할 때 A가 물었다.

A: TDD가 뭐에요? 왜 써야 하죠?
나: TDD는 테스트 코드를 먼저 작성하고 프로덕션 코드를 작성하는…. (중략) 설계 기법이고요. ~~한 장점이 있습니다.
A: 어? 그거 테스트 코드 작성했을 때의 장점 아니에요? 먼저 프로덕션 코드 작성하고 테스트 코드 작성하면 되지 않아요? 저는 테스트 코드 작성은 필수지만, TDD는 안 해도 된다고 생각해요.

'어 그러네..? 분명 TDD만의 장점이 있는데….' 나는 할 말을 잃었다. 왜 쓰는 걸까?
그 당시 나는 TDD의 장점을 이렇게 말했다.

  • 피드백이 빠르다.
  • 변화에 대한 두려움을 줄여준다. (리팩토링이 편하다)
  • TDD를 하면 코드 복잡도가 떨어진다.
  • 디버깅 시간을 줄여준다.
  • 동작하는 문서 역할을 한다.

다시 생각해보니 내가 말한 대부분의 장점은 테스트 코드를 작성했을 때의 장점이지 TDD만의 장점은 아니였다.

그래서 곰곰히 생각해보면서 나름대로 TDD만의 장점을 찾았다.

TDD의 장점

주변 사람에게 물어보고, 소프트웨어 장인 정신도 읽어보면서 내 나름대로 이해가 가는 장점들을 정리해봤다.

주의: 저의 주관적인 생각도 포함된 만큼 틀린 부분도 있을 수 있습니다.

오버 엔지니어링 방지

잘 정리된 요구사항의 역할도 하므로 딱 필요한 만큼만 코딩하도록 유도하여 불필요하게 복잡해지거나 오버 엔지니어링을 줄여준다.

내가 TDD를 하지 않았을 때 겪은 경험

당장 필요 없어도 미래에 필요할 거라고 지레짐작하여 불필요한 코드를 미리 작성했는데 결과적으로 끝까지 사용되지 않았다. TDD를 하면 이러한 코드를 방지해준다.

TDD를 하면 자연스레 테스트 커버리지가 높아진다.

테스트 코드를 먼저 작성하니까 당연한 이야기다.
"나중에 작성해도 테스트 커버리지는 높아지는데? 뭐가 달라?"

내가 TDD를 하지 않았을 때 겪은 경험

내 경험에 의하면 나중에 작성하면 잊어먹거나, 현재 기능이 잘 되니까 귀찮다고 미루는 경우가 있다. TDD는 이를 방지해준다.

아이디어를 생각해내는 데도 도움이 되고 한 번에 하나씩만 집중할 수 있다.

소프트웨어 장인 정신에 나오는 부분으로 모듈, 클래스, 메소드를 구체적으로 정의하도록 강제하여 일을 점진적으로 진행할 수 있다.

내가 TDD를 하지 않았을 때 겪은 경험

하나의 클래스, 메소드에 집중하지 못하고 관련된, 혹은 다른 여러 개를 동시에 작업하면서 흐름과 방향을 잃는 경우가 있었다. TDD를 하면 딱 하나에만 집중하게끔 강제하여 흐름을 잃지 않는다.

설계에 대한 피드백이 빠르다.

객체지향 설계에에 있어서 객체 간의 의존 관계는 필요하다. 중요한 것은 이 의존도를 낮추는 거다. 설계 단계에서 잘한다면 좋겠지만, 잘 못되었다면 언제 깨달을 수 있을까?
변경이 일어났을 때, 사용하기 어려울 때 깨달을 수 있다. 이러한 점에서 TDD는 설계에 대한 피드백을 빠르게 해준다.

예를 들면, 테스트 코드를 작성하는데 대상 코드가 잘못된 설계와 과도한 복잡도를 가지고 있으면 새로운 테스트 코드가 작성하기가 점점 어려워진다.

내가 TDD를 하지 않았을 때 겪은 경험

프로덕션 코드를 작성하고 테스트 코드를 작성하는데 테스트하기가 너무 어려웠다. 그 이유는 복잡한 의존관계 때문이었고 설계가 잘 못된 사실을 깨달은 나는 뒤늦게 다시 작성해야 했다.

TDD의 단점

개발 시간이 오래 걸린다?

경우에 따라 다르다. 테스트 코드를 아예 작성하지 않으면 모를까 똑같이 테스트 코드를 작성한다면 글쎄? 더 빠르면 빨랐지 느리진 않다고 생각한다.

진입 장벽

이게 가장 큰 걸림돌이라고 생각한다. 익숙지 않은 개발 방식의 어려움에 어떻게 해야 할지 감도 안 오고 스트레스받는다.

테스트는 설계를 위한 기법인가?

고민을 해결하니 또 다른 고민이 생겼다.
만약 TDD가 설계 방법론이라면 TDD만으로 좋은 설계가 나와야 할 텐데 TDD만으로 만족스러운 설계가 나온 경험이 없었다. 내 실력이 부족한 걸까? 아니면 다른 이유일까? 고민하다가 이규원님이 작성하신 TDD는 설계 방법론이 아니다 를 읽고 고민이 해결되었다.

결론만 말하자면, TDD는 좋은 설계가 만들어지게 도움은 주지만 TDD만으로 좋은 설계가 만들어지지는 않는다. 전적으로 TDD에만 설계를 의존하면 테스트하기 좋은 쓰레기를 얻게 된다. 좋은 설계는 성공적인 TDD의 필요조건이다. 하지만 TDD는 좋은 설계의 필요조건도 충분조건도 아니다. TDD는 설계 방법론이 아니다.

자세한 이야기는 이규원님이 작성하신 글과 [번역] TDD 변절자: TDD는 설계 기법이 아니다. 를 읽어보길 바란다.

결론

TDD는 코드의 설계, 단순성, 유지보수 용이성에 대해 피드백이 빠르다. TDD는 실수를 줄여주고 더 나은 설계가 나오도록 도와준다.
TDD를 하지 않아도 좋은 결과를 얻을 수 있다. 그러므로 스스로 잘할 수 있다면 굳이 하지 않아도 된다고 생각한다. 하지만 이는 쉽지 않다.

잘 못된 부분, 추가적인 장점, 단점 등 피드백 주시면 감사하겠습니다.

References

'Test' 카테고리의 다른 글

테스트 커버리지는 높을수록 좋을까?  (0) 2019.12.28