테스트 주도 개발의 핵심은 무엇인가?
1.1 학습 과정으로서의 소프트웨어 개발
- 프로젝트에서는 예상치 못한 요소가 많음.
- 불확실성을 해결하는 데 도움이 될 프로세스가 필요.
1.2 피드백은 가장 기본적인 도구다
- 경험에 의거한 피드백
- 반복적인 활동 주기
- 점진적이고 반복적인 개발
1.3 변화를 돕는 실천법
- 회귀 오류를 잡아줄 꾸준한 테스트 - 자동화된 테스트
- 코드를 가능한 한 단순하게 유지 - 꾸준한 리팩터링
- 테스트 주도 개발
- 코드를 작성하기 전에 테스트를 작성
- 테스트를 설계 활동으로 변경.
- 자동화된 회귀 테스트라는 안전망.
1.4 테스트 주도 개발 간단 정리
TDD 핵심 주기

- 테스트 작성
- 테스트가 동작하게 만드는 코드 작성
- 단순한 구현으로 리팩터링
테스트 작성의 장점
- 작업에 대한 인수 조건이 명확해짐.
- 느슨하게 결합된 구성 요소 작성.
- 코드에 대한 실행 가능한 설명 추가.
- 완전한 회귀 스위트 증가
테스트 실행의 장점
- 오류를 탐지
- 과도한 최적화, 불필요한 기능 추가를 방지
테스트 주도 개발의 황금률 - 실패하는 테스트 없이는 새 기능을 작성하지 말라.
1.5 좀 더 큰 그림
언제 코드 작성을 멈춰야 하는가? - 실패하는 테스트로 시작해야 하는 이유
인수 테스트(acceptance test)

- 만들고자 하는 기능을 시험하는 테스트.
- 실패하는 동안은 해당 기능이 구현되지 않았음을 보임.
- 직접 관련된 코드만 작성하게 유도.
1.6 전 구간 테스트
- 인수 테스트에서는 시스템 전 구간을 테스트해야 함.
- 전 구간 테스트(end-to-end test)는 외부에서 유입되는 시스템(사용자 인터페이스를 통하거나 서드 파티 시스템에서 온 것처럼 메시지를 전송하거나 웹 서비스를 호출하거나 보고서를 구문 분석하는 등의 방식)과 상호작용.
1.7 테스트의 수준
- 인수 테스트: 전체 시스템이 동작하는가?
- 통합 테스트: 변경할 수 없는 코드를 대상으로 코드가 동작하는가?
- 단위 테스트: 객체가 제대로 동작하는가? 객체를 이용하기가 편리한가?
1.8 외부 품질과 내부 품질
외부 품질과 내부 품질의 구분
- 외부 품질: 시스템이 고객과 사용자의 요구를 얼마나 잘 충족하는가(기능, 신뢰성, 가용성, 응답성 등)
- 내부 품질: 시스템이 개발자와 관리자의 요구를 얼마나 잘 충족하는가(이해하기 쉬운가, 변경하기 쉬운가 등)
- 전구간 테스트 - 시스템의 외부 품질 파악 가능.
- 단위 테스트 - 시스템의 내부 품질 파악 가능.
철저한 단위 테스트
- 철저한 단위 테스트는 내부 품질을 개선하는 데 도움.
- 테스트 픽스처에서 해당 단위를 시스템 바깥에서 실행할 수 있게 구조화를 유도.
- 좋은 설계
테스트 주도 개발의 핵심은 무엇인가?
2.1 객체망
객체 지향 설계는 객체 자체보다 객체 간의 의사소통에 더 집중
- 중요한 것은 메시지 전달
- 객체는 메시지로 의사소통. 메시지를 보낸 객체에 값이나 예외를 반환.
- 자신이 이해할 수 있는 메시지를 처리하는 메서드(method)가 존재.
- 내부 상태를 캡슐화.
객체 지향 시스템은 협업하는 객체의 망으로 구성
- 시스템은 객체를 생성해 서로 메시지를 주고받을 수 있게 조립하는 과정을 거쳐 만들어짐.
- 시스템에 포함된 객체의 구성을 변경해 시스템 작동 방식을 변경할 수 있음.
- 선언적 정의(declarative): 객체 구성을 관리할 목적으로 작성하는 코드
2.2 값과 객체
값(value)
- 변하지 않는 양이나 크기를 의미
- 양이 고정된 불변 인스턴스
- 상태(값)이 같으면 동일
객체(object)
- 시간이 지남에 따라 상태가 변하며, 식별자(identity)가 있는 계산 절차(computational process)를 의미
- 변경 가능한 상태를 가지며, 시간의 추이에 따른 객체의 행위를 나타냄.
- 식별자가 같아야 동일
2.3 메시지를 따르라
- 다른 객체와 쉽계 관계를 맺을 수 있게 객체를 설계하면 고수준의 선언적 접근법이 주는 혜택을 누릴 수 있음.
- 객체는 일반적인 의사소통 패턴을 따르고 객체 간의 의존성은 명시적이어야 함.
역할, 책임, 협력자
- 역할: 관련된 책임의 집합
- 책임: 어떤 과업을 수행하거나 정보를 알아야 할 의무
- 협력: 객체나 역할의 상호 작용
- 객체는 하나 이상의 역할을 구현한 것.
2.4 묻지 말고 말하라
디미터 법칙(Law of Demeter)
- 객체는 내부적으로 보유하고 있거나 메시지를 통해 확보한 정보만 가지고 의사 결정을 내려야 함.
2.5 그래도 가끔은 물어라
값과 컬렉션으로부터 정보를 가져오거나 팩터리를 이용해 새 객체를 생성할 때는 물어도 됨.
2.6 협력 객체의 단위 테스트
객체가 호출될 떄 이웃 객체에 메시지를 보내는 경우, 이웃 객체의 내부 상태를 드러내지 않고 메시지가 올바르게 수행되는지 테스트하는 법.
이웃 객체를 목 객체(mock object)로 대체.
- 대상 객체가 가짜 이웃과 어떻게 상호 작용할지 지정 가능 - 예상 구문(exprectation)
- 목 객체가 예상대로 호출됐는지 단정.
- 나머지 테스트가 동작하는 데 필요한 행위(스텁)을 구현할 수 있음.
2.7 목 객체를 활용한 TDD 지원
- 필요한 목 객체 생성
- 대상 객체를 포함한 실제 객체 생성
- 대상 객체에서 목 객체가 어떻게 호출될지 예상하는 바를 기술
- 대상 객체에서 유발(trigger) 메서드(하나 또는 여러개)를 호출
- 결과 값이 유효하고 예상되는 메서드 호출이 모두 일어났는지 확인
도구 소개
3.2 간략한 JUnit 4 소개
3.2.4 테스트 팩스처
- 테스트 픽스처(test fixture): 테스트가 시작할 때 존재하는 고정된 상태.
- 테스트가 반복 가능함을 보장.
- 테스트가 실행되기 전에 준비(set up) 테스트 실행이 완료된 후 정리(tear down)
3.3 햄크레스트 매처와 aseertThat()
3.4 jMock2: 목 객체
- 테스트 대상 객체가 상호 작용 중인 목 객체를 어떻게 호출하고 목 객체가 거기에 반응해 어떻게 동작해야 할지를 지정하는 고수준 API를 제공
출처