TDD 마무리

Young Min Sim ·2021년 7월 13일
0

TDD

목록 보기
6/6

TDD를 함에 있어 필요한 질문들을 다룬다.


단계가 얼마나 커야 하나 ?

이 질문은 사실 2가지 질문을 내포하고 있다.

  • 각 테스트가 다뤄야 할 범위는 얼마나 넓은가?
  • 리팩토링을 하면서 얼마나 많은 중간 단계를 거쳐야 하는가?

한 줄 정도의 작은 크기의 테스트를 만들 수 있는가 하면, 수백 줄의 로직과 수시간 분량의 리팩토링을 할 만큼의 크기를 갖는 테스트를 만들 수도 있다. 이 중 어떤 것인 옳은가? -> 답은 '둘 다 할 수 있어야 한다.'

TDD에 익숙해질수록 단계의 크기가 점점 작아질텐데, 몇몇은 애플리케이션 수준의 TDD를 만들기도 한다.

다만 책의 저자도 '난 앞으로도 (애플리케이션이 아닌) 프로그래머 수준의 TDD를 선호할 것 같다'고 말하고, 일반적으로는 애플리케이션 수준의 TDD를 하지는 않을 것 같으므로 적당하게 작은 크기의 테스트를 만드는 것만으로도 충분하지 않나 생각함


테스트할 필요가 없는 것은 무엇인가?

'두려움이 지루함으로 변할 때까지 테스트를 만들어라' 라는 대답이 있다. 하지만 이건 어디까지나 일반적인 대답일 뿐 스스로 답을 찾아야 한다.
책의 저자는 '자신이 작성하는 것에 대해서만 테스트하라. 불신할 이유가 없다면 다른 사람이 만든 코드를 테스트하지 마라.'라고 덧붙이고 있음.


좋은 테스트를 갖췄는지의 여부를 어떻게 알 수 있는가?

다음은 설계 문제가 있음을 알려주는 테스트의 속성이다.

  • 긴 셋업 코드: 하나의 단순한 단언(assert)를 수행하기 위해 수백 줄의 객체 생성 코드가 필요하다면 객체가 너무 크다는 뜻으로 나눌 필요가 있다.
  • 셋업 중복: 공통의 셋업 코드를 넣어 둘 공통의 장소를 찾기 힘들다면 서로 밀접하게 엉킨 객체들이 너무 많다는 뜻이다.
  • 실행 시간이 오래 걸리는 테스트: 실행하는데 오래 걸리면 테스트를 실행하지 않게 되고 테스트를 방치하게 된다. 이보다 더 나쁜 점은, 테스트의 실행 시간이 오래 걸린다는 것은 작은 부분만 별도로 테스트하기가 힘들다는 것이다. 이는 즉 설계의 문제를 의미하고 설계를 바꿔줄 필요가 있다.
  • 깨지기 쉬운 테스트: 예상치 못하게 깨지는 부분이 있다는 것은 즉, 특정 부분이 다른 부분에 이상한 방법으로 영향을 끼치고 있다는 것이다. 연결을 끊거나 두 부분을 합하는 것을 통해 멀리 떨어진 것의 영향력이 없어지도록 설계해야 한다.

결국은 이 4가지의 해결법은 객체의 책임을 잘 나누어 이 문제들을 해결하고 좋은 테스트를 갖출 수 있다.


테스트를 지워야 할 때는 언제인가?

책 내용 중 '개념적으로 동일한 테스트가 있으면 중복으로 간주하고 제거한다' 라는 내용이 있었는데 이에 대해 좀 더 명확한 설명을 하고 있음

테스트가 많으면 좋기는 하지만, 서로 겹치는 두 개의 테스트가 있어도 이들을 남겨두어야 하는가?

대답은 두 가지 기준에 의해 결정된다.

  • 첫째 기준은 자신감이다. 테스트를 삭제할 경우 자신감이 줄어들 것 같으면 절대 테스트를 지우지 말아야 한다.
  • 둘째 기준은 커뮤니케이션이다. 두 개의 테스트가 코드의 동일한 부분을 실행하더라도, 이 둘이 서로 다른 시나리오를 말한다면 그대로 남겨두어야 한다.

프로젝트 중반에 TDD를 도입하려면 어떻게 해야 할까?

가장 큰 문제는, 테스트를 염두에 두지 않고 만든 코드는 테스트하기가 그리 쉽지 않다는 것이다. 일부분만을 격리해서 실행하고 결과를 검사할 수 있게끔 인터페이스가 설계되어 있지 않다. '고치면 되잖아'라고 할 수도 있지만 테스트가 없기 때문에 에러가 생겼다는 점을 알아낼 수 없을 것이다. 즉, 교착상태에 빠진다.

우선 해야 할 일은 변경의 범위를 제한하는 것이다. 시스템에서 극적으로 단순화될 수 있지만 지금 당장 변할 필요가 없는 부분을 봤다면 그냥 그대로 둔다.

즉, 새로 추가한 기능 혹은 리팩토링이 필요한 코드에 대해서만 TDD를 한 번씩 이용해봐도 괜찮지 않을까?

그 다음으로 해야 할 일은 테스트 - 리팩토링 사이의 교착 상태를 푸는 것이다. 테스트가 아닌 다른 방법으로도 리팩토링에 대한 피드백을 얻을 수 있다. 예를 들어 아주 조심스럽게 작업하는 방법이나 파트너와 함께 작업하는 방법 등이 있다.

테스트에 용이한 구조 즉, 구현 시에 객체 간 결합도가 낮게, 책임이 잘 분리되도록 구현하는게 중요한 것 같다. (테스트 뿐만 아니라) 가독성, 유지보수 측면에서 많은 도움이 된다.


TDD는 누구를 위한 것인가?

훌륭한 엔지니어링은 프로젝트 성공의 20%에 불과할 수도 있다. 나머지 80%가 어느 정도 제대로 된다면 적당한 수준의 엔지니어링만으로도 프로젝트는 성공할 수 있다. 이러한 측면에서 봤을 때 TDD는 오버액션이다.

TDD는 현재 업계에서 통용하는 수준보다 훨씬 더 적은 수의 결함과 훨씬 더 깨끗한 설계의 코드를 작성하게 해준다.

  • 코드의 우아함을 찾는 사람들에게 좋다
  • 프로젝트가 진행됨에 따라 코드에 대한 자신감을 점점 더 쌓아갈 수 있다.

아직도 여전히 TDD에 대한 확신이 없지만, 이제는 '코드에 대한 자신감'이 어떤 의미인지는 충분히 이해할 수 있음.


TDD와 패턴의 관계는?

이 책의 저자가 패턴에 대한 장을 작성한 이유는, '근본적 규칙을 찾으려는 노력'이었다.
여기서 강조하고자 하는 것은, '반복적 행동을 규칙으로 바꿈으로써 규칙을 적용하는 것은 기계적이며 단순 암기가 된다는 점'이다.
예외 혹은 규칙의 어느 것도 들어맞지 않는 문제가 있을 경우 새로운 것을 창조하고 적용할 더 많은 시간과 에너지를 갖게 된다.

설계를 정해두고 문제를 해결하려기 보다는 문제를 해결하다 보면 자연스럽게 결정되는 설계 패턴을 사용하는 것이 좋다.


실제로 프로젝트에 적용하지 못하더라도 알고 있는 상태에서 쓰지 않는 것과 알지 못해서 쓰지 못하는 것의 차이점은 크다고 생각하는데요, 부스트캠프/우테크 등의 교육 부트캠프나 혹은 신입사원 교육에서도 짧게 몇 시간 정도 간단한 문제를 내주고 짝 프로그래밍과 TDD를 이용해서 해결해보는 시간을 가져 보는 것도 재밌을 것 같다는 생각이 들었습니다.

0개의 댓글