일단 1회독은 했는데, 아직까지 이해하기 어려운 예시도 있었다. 개발 경험을 점점 쌓아가면서 다시 한 번 읽어 보면 좋을 듯 하다. 일단 이해가 가능하고 중요한 부분 위주로 정리를 해 보았다.
TDD를 마스터하기 위해서 작은 단계로 작업하는 연습이 필요하다. 마스터하면 훨씬 큰 기능 단계로 작업할 수 있지만, 처음에는 작은 단계로 연습을 해 보는 것이 좋다. 필요할 때 작은 단계로 작업할 수 있어야 하기 때문이다.
한 번에 메서드를 하나 이상 수정하지 않으면서 테스트가 통과하게 만들 수 있는 방법을 찾아내는 것이 좋다.
테스트를 하기 위해 객체를 생성하면 두 가지 제약이 상충한다. 객체 하나만 생성하여 여러 테스트에서 사용하면 성능상으로 이점을 가지지만, 그 객체를 수정했을 때 다른 테스트에서 오류가 날 수 있다. 따라서 테스트 커플링을 만들지 않는 것이 중요하다.
따라서 테스트를 처음 만들 때는 객체를 하나하나 생성하여 각각의 테스트가 잘 동작하는지 확인한 후, 일반화 시키는 것이 좋다.
리팩토링했다가 이를 다시 되돌리는 것은 흔한 일이다.
테스트를 선택할 때는 나에게 뭔가 가르침을 줄 수 있고 내가 만들 수 있다는 확신이 드는 것을 선택한다. 테스트를 하나 성공시켰는데 그 다음 테스트를 만들며 문제가 생기면 두 단계 뒤로 물러서는 것을 고려하라.
테스트는 다른 테스트와 완전히 독립적이어야 한다. 즉, 문제가 하나면 테스트도 하나만 실패해야 하고, 문제가 둘이면 테스트도 두 개만 실패해야 한다.
격리된 테스트가 암묵적으로 내포하는 특징 중 하나는 테스트가 실행 순서에 독립적이게 된다는 점이다. 테스트의 일부만 실행해보고 싶으면, 선행 테스트가 실행되지 않아서 내가 고른 테스트들이 실패하지 않을까 걱정할 필요 없이 그렇게 할 수 있어야 한다.
테스트 주도 개발을 할 때는 우선 구현할 필요가 있는 모든 오퍼레이션의 사용 예들을 적는다. 그 다음, 이미 존재하지 않는 오퍼레이션에 대해서 오퍼레이션에 널 버전(아무 일도 하지 않는 버전)을 리스트에 적는다. 마지막으로 깔끔한 코드를 얻기 위해 이번 작업을 끝내기 전에 반드시 해야 할 리팩토링 목록을 적는다.
테스트 작성은 테스트 대상이 되는 코드를 작성하기 직전에 작성하는 것이 좋다.
데이터의 의도를 표현할 때는 명백한 데이터를 사용할 수 있다. 예를 들어, 숫자 49.25 대신 100/2*(1-0.015) 같이 식을 사용한다면 입력으로 사용된 숫자와 예상되는 숫자 사이의 관계를 읽어낼 수 있다.
키보드로 뭘 쳐야 할지 알면, 명백한 구현을 한다. 잘 모르겠다면 가짜 구현을 한다. 올바른 설계가 명확하지 않다면 삼각측량 기법을 사용한다. 그래도 모르겠다면 샤워를 하러 간다.
지나치게 큰 테스트 케이스의 경우, 원래 케이스의 깨지는 부분에 해당하는 작은 테스트 케이스를 작성하고 그 작은 테스트 케이스가 실행되도록 한다. 그 후에 다시 원래의 큰 테스트 케이스를 추가한다.
혼자 작업한다면, 깨진 테스트를 만들어 놓고 작업을 종료한다. 오랜 시간 후에 작업할 때, 해야할 부분을 명확히 찾을 수 있다. 하지만 팀으로 작업한다면 코드를 항상 완성해 놓는 게 좋다.
객체 컬렉션을 다루는 연산은, 일단 컬렉션 없이 구현하고 그 다음에 컬렉션을 사용하게 한다.
설계 문제가 있음을 알려주는 테스트의 속성
긴 셋업 코드 : 하나의 단순한 단언을 수행하기 위해서 수백 줄의 객체 생성 코드가 필요하다면 문제가 있는 것이다.
셋업 중복 : 공통의 셋업 코드를 넣어 둘 공통의 장소를 찾기 힘들다면, 서로 밀접하게 엉킨 객체들이 너무 많다는 뜻이다.
실행 시간이 오래 걸리는 테스트
깨지기 쉬운 테스트 : 예상치 못하게 실패하는 테스트가 있다면 특정 부분이 다른 부분에 이상한 방법으로 영향을 끼친다는 뜻이다.
테스트를 지워야 할 때
테스트를 지워도 자신감이 떨어지지 않을 때.
두 개의 테스트가 코드의 동일한 부분을 실행하더라도, 둘이 서로 다른 시나리오를 말한다면 그대로 남겨두어야 한다.
비슷해 보이는 두 코드 조각을 합치려면 두 코드를 단계적으로 닮아가게 수정한다. 이 둘이 완전히 동일해지면 둘을 합친다.
너무 코드 흐름이 꼬여있다면 메서드를 다시 인라인시킨 다음 흐름을 이해하고 다시 추상화한다.
한 메서드에서 다른 객체에 하나 이상의 메시지를 보내는 것을 보면 메서드를 옮기는 것이 좋다.
여러 개의 매개 변수와 지역 변수를 갖는 복잡한 메서드는 메서드를 꺼내서 객체로 만든다.