Sum.plus()와 Money.plus()사이의 지저분한 중복이 남아있다.
Expression을 인터페이스에서 클래스로 바꾼다면, 공통되는 코드를 담을 수 있는 적절한 곳이 될것이다.
TDD를 완벽을 위한 노력의 일환으로 사용하면 효과적인 용법이 아니다.
만약 시스템이 크다면, 내가 건드리는 부분들은 절대적으로 견고해야 한다. 그래야 나날이 수정할 때 안심할 수 있기 때문이다.
"다음에 할일은 무엇인가?" 라는 말은 "어떤 테스트들이 추가로 필요할까?" 이다.
때로 실패해야 하는 테스트 케이스가 성공할 때에는 그 이유를 반드시 찾아내야 한다.
저자가 Money 예제를 코딩하면서 가장 놀라운 점은 이번 Money 예제의 결과가 기존에 했던것과 많이 다르다는 것이다.
저자의 기준으로 실무에서 최소 3번 이상의 금전 관련 프로그램을 작성했고 출판물에서도 대여섯 번 이상 예제로 사용했다.
그리고 이 글을 쓰는 동안 expression 메타포를 생각했는데, 설계가 기존과는 완전히 다른 방향으로 흘렀다.
expression 메타포는 중복되는 통화를 합치는 세세한 일단의 문제에서 해방시켰고, 코드도 어느때보다도 명확해져갔다.
-> 솔직히 나는 너무 햇갈렸는데... 뭐 그렇다고 한다.
저자가 Money예제를 코딩하는 동안 로그를 기록하게 해두었고, 보통 1분에 한번정도 테스트를 실행했다.
전체 API를 다 구현한게 아니기 때문에 함수의 수나 클래스당 함수의 수, 클래스당 줄 수 등을 절대적으로 평가할수는 없다.
하지만 그 상대적인 비율에서 교훈을 얻을 수 있을 것이다.
- 코드와 테스트 사이에 대략 비슷한 양의 함수와 줄이 있는 것을 알수 있다.
- 테스트 코드의 줄 수는 공통된 테스트 픽스쳐를 뽑아내는 작업을 통해 줄일수 있다. 하지만 모델 코드와 테스트 코드 사이의 대략적인 줄 수는 비슷하게 유지될 것이다.
- 테스트 코드에 분기나 반복문이 전혀 없기 떄문에 테스트 복잡도는 1이다. 명시적인 흐름 제어 대신 다형성을 주로 사용했기 때문에 실제 코드의 복잡도도 낮다.
- 함수의 선언부와 닫는 괄호도 포함된 줄 수다.
- 테스트의 함수당 줄 수가 과장되었는데 이는 공통된 픽스처 구축코드를 추출하지 않았기 때문이다.
- 작은 테스트를 추가한다.
- 모든 테스트를 실행하고, 실패하는 것을 확인한다.
- 코드에 변화를 준다.
- 모든 테스트를 실행하고, 성공하는 것을 확인한다.
- 중복을 제거하기 위해 리팩토링 한다.
TDD의 부산물로 자연히 생기는 테스트들은 시스템의 수명이 다할 때까지 함께 유지돼야 할 만큼 확실히 유용하지만,
이 테스트들이 다음과 같은 다른 종류의 테스트들을 대체할 수 있을거라고 생각해서는 안된다.
- 성능 테스트
- 스트레스 테스트
- 사용성 테스트
TDD를 가르칠 때 사람들이 자주 놀라는 세 가지는
- 테스트를 확실히 돌아가게 만드는 세 가지 접근법: 가짜로 구현하기, 삼각측량법, 명백하게 구현하기.
- 설계를 주도하기 위한 방법으로 테스트 코드와 실제 코드 사이의 중복을 제거하기
- 길이 미끄러우면 속도를 줄이고 상황이 좋으면 속도를 높이는 식으로 테스트 사이의 간격을 조절할 수 있는 능력