# 1부. 테스트 주도 개발 기초
###### tags: `지호`, `이규원의 현실 세상의 TDD : 안정감을 주는 코드 작성 방법`
---
## 1. 코드 기능 명세
### 코드 기능 명세
- 모든 프로그램 코드는 입력과 출력을 갖고 특정 입력에 대해 기대하는 출력이 있다
- 이런 기대 동작들을 코드의 명세 또는 요구사항이라고 부른다
### 도메인
- 소프트웨어는 문제를 푸는 도구
- 도메인은 소프트웨어가 풀어야 할 문제가 정의되는 공간
### 프로그래머와 기능 명세
- 명확한 기능 명세가 있어야 프로그래머가 올바른 동작을 하는 코드를 짤 수 있다
- 충분히 명확한 도메인 지식을 확보하지 못했다면 지식 보가을 요청해야 한다
<br/>
## 2. 테스트 기법
### 수동 테스트
- 품질 담당자가 UI를 사용해 기능을 검증
- 최종 사용자의 사용 경험과 가장 비슷하게 검증
- 실행 비용이 높고 결과의 변동이 큼 (단점)
- 가장 온전한 코드 실행
- 인수 테스트에 사용됨
### 소프트웨어 회귀
- 원래 동작하던 기능이 어떤 시점 이후로 동작하지 않게 되는 현상
- 새로운 기능이 추가됐을 때, 배포를 했을 때
### 테스트 자동화
- 기능을 검증하는 코드를 작성
- 테스트 코드 작성 비용이 소비되지만, 실행 비용이 낮고 결과의 신뢰도가 높음
- 테스트 코드 작성과 관리가 프로그래머 역량에 크게 영향을 받음
### 인수 테스트
- 배치가 완료된 시스템을 대상으로 검증
- 전체 시스템 이상 여부 신뢰도가 높음
- 높은 비용: 작성 비용, 관리 비용, 실행 비용
- 피드백 품질이 낮음: 문제의 원인이 무엇인지 알기 힘듦
### 단위 테스트
- 시스템의 일부(하위 시스템)을 대상으로 검증
- 낮은 비용: 작성 비용, 관리 비용, 실행 비용
- 높은 피드백 품질
- 전체 시스템 이상 여부 신뢰도가 낮음
### 인수 테스트와 단위 테스트
- 인수 테스트는 시스템 외부에 노출된 영역을 대상으로 진행
- 단위 테스트는 시스템 내부에 있는 하위 시스템을 대상으로 진행
<br/>
## 3. 코드 분해
### 모듈화
- 분해
- 큰 시스템은 더 작은 하위 시스템으로 분해 가능
- 교체 가능
- 조립
- 작은 시스템은 더 큰 상위 시스템으로 조립 가능
- 모듈 재사용
- 라이브러리
<br/>
## 4. 테스트 우선 개발
### 테스트 코드
- 가시적이고 구체적인 목표
- 자가 검증 가능
- 반복 실행 가능
- 운영 코드 API의 클라이언트가 됨
### Test Firtst Development
- 운영 코드보다 테스트 코드를 먼저 작성
- 테스트 코드를 통과시킬 운영 코드를 작성
- 프로그래머가 명확하고 검증 가능한 목표를 설정한 후 목표를 달성
<br/>
## 5. 정리된 코드
### 리팩토링
- 리팩토링 전/후에 생길 수 잇는 기능 변화들을 테스트 코드로 검사해야한다.
<br/>
## 6. 테스트 주도 개발
### 테스트 주도 개발 절차
- RED
- 운영 코드를 작성하기 전에 테스트 코드를 먼저 작성
- 실패하는 테스트 추가
- GREEN
- 운영 코드를 수정해서 새로 작성한 테스트와 기존에 작성한 테스트를 성공
- 최소한의 코딩
- REFACTOR
- 테스트 통과된 결과를 유지하면서 코드를 리팩토링
- 구현 설계 개선
### 테스트 실패
- 구체적인 하나의 요구사항을 검증하는 하나의 테스트 추가
- 추가된 테스트가 실패하는지 확인
- 실패하는 것을 확인해야 테스트가 동작함을 믿을 수 있다.
- 운영 코드 변경이 진행되지 않았기 때문에 실패했는지 확인해야 한다.
### 테스트 성공
- 추가된 테스트를 비롯해 모든 테스트가 성공하도록 운영 코드를 변경
- 테스트 성공은 요구사항 만족을 의미
- 테스트 성공을 위한 최소한의 변경
### 리팩토링
- 코드 베이스 정리
- 구현 설계 개선: 가독성, 적응성, 성능
- 모든 테스트 성공을 전제
### 켄트 벡의 설계 규칙
- 테스트 통과
- 의도 노출
- 중복 제거
- 테스트 통과되는 코드만 유지
### 테스트 주도 개발 비용
- 처음엔 높은 비용으로 시작하지만, 시간이 지나도 비용이 일정 수준으로 유지
- TDD를 사용하지 않으면 처음엔 비용이 낮지만, 어느 순간은 계속 비용이 늘어남
<br/>
## 7. 기대 출력 피드백
### 기대 출력 피드백
- 사용자 피드백: 사용자가 직접 코드를 사용한 후 경험한 버그나 불만을 제보
- Quality Assurance: 전문 인적 자원에 의한 인수 테스트
- 프로그래머 테스트: 프로그래머가 직접 피드백 장치를 준비
- 도구 피드백: 컴파일 오류, 정적 검사 등 프로그래머가 사용하는 도구가 제공하는 피드백
### 오버 엔지니어링
- 더 중요한 목적, 기능 요구사항에 써야 할 자원을 불필요하게 낭비하게 됨
- 테스트 주도 개발은 가장 중요한 목표를 우선 달성하도록 유도하며 피드백을 제공 (모든 테스트가 성공)
### 피드백
- 테스트 주도 개발의 핵심은 정해진 절차가 아니라 짧은 주기로 지속되는 피드백
- 피드백에 기반해 안정적으로 지식과 코드를 늘려나가는 것이 목적