리팩터링은 분명 가치 있는 도구지만, 그것만으로는 부족하다. 리팩터링을 제대로 하려면 불가피하게 저지르는 실수를 잡아주는 견고한 **테스트 스위트$^{1)}$**가 뒷받침돼야 한다

리팩터링을 하지 않더라도 좋은 테스트를 작성하는 일은 개발 효율을 높여준다

테스트 스위트 : 테스트 케이스(여기서 이것은 하나의 메소드를 테스트하기 위한 테스트 메소드를 의미)들을 하나로 묶은 것

자가 테스트 코드의 가치

프로그래머들은 대부분의 시간은 디버깅에 쓴다. 버그 수정 자체는 대체로 금방 끝나지만 끔찍한 건 버그를 찾는 여정이다

저자는 코드베이스에 프로덕션 코드와 테스트 코드를 함께 담기로 했다. 반복적 개발 방법론을 따르고 있었기에 반복 주기가 하나 끝날 때마다 가능하면 테스트 코드도 추가했다. 테스트 작업은 쉽고 간단했지만 콘솔에 출력한 결과를 일일이 눈으로 확인해야 했기에 지루했다. 그래서 모든 테스트가 성공하면 화면에 “OK”만 출력하도록 만들었다. 이렇게 자가 테스트 소프트웨어가 탄생했다

모든 테스트를 완전히 자동화하고 그 결과까지 스스로 검사하게 만들자

컴파일할 때마다 테스트로 함께 했고, 곧바로 생산성이 급상승했다. 디버깅 시간이 크게 줄었기 때문이다.

이 사실을 깨달은 후, 테스트에 더 적극적으로 되었고 반복 주기가 끝나길 기다리지 않고 함수 몇 개만 작성해도 곧바로 테스트를 추가하기 시작했다

테스트 스위트는 강력한 버그 검출 도구로 버그를 찾는데 걸리는 시간을 대폭 줄여준다

테스트가 실제로 프로그래밍 속도를 높여주는 경험을 직접 해보지 않고서는 자가 테스트의 진가를 납득하긴 어렵다. 테스트를 작성하기 가장 좋은 시점은 프로그래밍을 시작하기 전이다

얼핏 순서가 뒤바뀐 듯 들리지만, 테스트를 작성하다보면 원하는 기능을 추가하기 위해 무엇이 필요한지 고민하게 된다. 구현보다 인터페이스에 집중하게 된다는 장점도 있다. 코딩이 완료되는 시점을 테스트를 모두 통과하는 시점으로 정확하게 판단된다

켄트 벡은 이처럼 테스트부터 작성하는 습관을 바탕으로 테스트 주도 개발 TDD란 기법이 창시되었다

테스트할 샘플 코드

첫 번째 테스트

▪︎실패해야 할 상황에서는 반드시 실패하게 만들자

수많은 테스트를 실행했음에도 실패하는 게 없다면 테스트가 내 의도와는 다른 방식으로 코드를 다루는 건 아닌지 불안해진다면, 일시적으로 코드에 오류를 주입하여 실패하는 모습을 최소한 한 번씩은 직접 확인한다

▪︎자주 테스트하라. 작성 중인 코드는 최소한 몇 분 간격으로 테스트하고, 적어도 하루에 한 번은 전체 테스트를 돌려보자

추가한 코드에 문제가 없는지, 혹은 리팩터링하면서 실수한 것이 없는지 확인하기 위해서다