---
# System prepended metadata

title: 2부. 테스트 주도 개발의 깊은 곳
tags: ['이규원의 현실 세상의 TDD : 안정감을 주는 코드 작성 방법', 지호]

---

# 2부. 테스트 주도 개발의 깊은 곳

###### tags: `지호`, `이규원의 현실 세상의 TDD : 안정감을 주는 코드 작성 방법`

---

## 1. 인터페이스와 구현

### 협력과 계약
- 대부분의 코드는 다른 코드와 협력
- 협렉에 필요한 것은 '어떻게'가 아닌 '무엇'
- 인터페이스
    - '무엇'을 표현
    - 클라이언트 코드에게 반드시 필요한 정보
    - 협력하는 코드 사이의 계약
    - 추상화 결과


### 정보 숨김
- 효과적인 모듈화
    - 조직 간 의사소통 최소화
    - 변경 여파 최소화
    - 시스템 이해 도움
- 공개된 설계 결정과 숨겨진 설계 결정
    - 어려운 설계 결정과 변경될 것 같은 설계 결정을 숨겨라


<br/>

## 2. 환경 변화와 적응령

### 개체 지향 (Object-oriented)
- 지연된 바인딩
- 다형성
    - 일반성

### 개방-폐쇄 원칙 (Open-closed principle)
- 소프트웨어 엔터티(클래스, 모듈, 함수 등)는 확장에 열리고 수정에 닫혀야 한다.
- 상속을 염두에 둔 정의

<br/>

## 3. 입력과 출력

### 입력과 출력
- 입력 -> 논리 -> 출력
- 직접 입려과 직접 출력
    - 공개된 인터페이스를 통한 입력과 출력
    - 다루기 간단함
- 간접 입력과 간접 출력
    - 입력된 인터페이스를 통한 입력과 출력
    - 다루기 복잡함

### 부작용
- 인터페이스 설계에 드러나지 않은 출력: 반환 값 외 출력
- 자주 사용되는 부작용: 실패, 지연, 간접 출력

<br/>

## 4. 테스트 대역

### 대역과 가정
- DOC 준비 비용이 큰 경우
    - 구동에 많은 자원이 필요
    - 환경 제어가 어려움
- DOC가 SUT에 제공하는 계약(인터페이스)을 준수하는 대역 코드를 사용
- 대역 코드가 계약을 DOC와 동일하게 준수할 것이라고 가정

### Dummy 
- SUT 준비를 위해 해결되어야 하는 의존성이 테스트 대상 논리에 의해 사용되지 않는 경우에 의존 요소를 대신하는 테스트 대역

### Stub
- 간접 입력 대역
- 미리 준비된 답을 출력

### Spy
- 간접 출력 대역
- SUT의 간접 출력을 기록

### Mock
- SUT내부의 행위(상호작용) 검증

### Facke
- 의존성 계약을 준수하는 가벼운 구현체
- DOC보다 적은 부작용
- 인메모리 데이터베이스 등

<br/>

## 5. Mockists vs Classicists

### Sociable 테스트
- 단위 테스트 -> 시스템 -> 의존 대상

### Solitary 테스트
- 단위 테스트 -> 시스템 -> 테스트 대역

### Mock의 위험
- 상태 검증 vs 행위 검증
- 정보 숨김 위배
- 테스트가 SUT 구현에 의존
- 고통스럽고 불안한 리팩토링

<br/>

## 6. Should I test private methods

### 비공개 모듈 테스트
- 비공개 모듈의 작성과 사용은 공개 모듈의 구현 영역
- 비공개 모듈 테스트는 공개 모듈 구현 노출
    - 테스트가 공개 모듈 구현에 의존
    - 정보 숨김 위배
    - SUT와 테스트 사이의 높은 결합

<br/>

## 7. 테스트 주도 설계

### 설계가 단위 테스트에 미치는 영향
- 테스트는 인터페이스 설계에 의존
- 인터페이스 설계 품질이 낮으면 테스트 작성이 불편함


### 단위 테스트가 설계에 미치는 영향
- 테스트가 있기 때문에 리팩토링 가능
- 두려움 없이 구현 설계를 과감하게 개선

### 단위 테스트에 의지하는 인터페이스 설계
- 단위테스트
    - 낮은 응집에 대한 피드백을 주지 않는다.
    - 일관된 설계를 강요하지 않는다.
    - 의도 노출을 요구하지 않는다.

### 단위 테스트에 의자하는 구현 설계
- 단위 테스트는 책임 분산을 유도하지 않는다.
- Mockists 
- 비공개 운영 코드 테스트

<br/>

## 8. 테스트 주도 개발의 한계

### 은탄환은 없다
- 테스트 주도 개발은 유용하고 매력적인 도구
- 하지만 테스트 주도 개발 역시 남용을 주의해야 한다.

### 불안정한 목표
- 모든 코드의 목표가 안정적이지 않음
- 탐색적으로 목표를 찾아내야 한다면 테스트 코드 작성 비용 부담이 큼

### 환경 제어
- 하위 시스템이 협력하는 다른 하위 시스템, 의존성 중 일부는 출력의 예측과 제어가 어려움 
    - 단위 테스트는 결정적일수록 유용
- 의존성 중 일부는 동작이 매우 느림
    - 단위 테스트는 빠를수록 유용
- 의존성의 단점을 보완할 대역을 도입하면 가정이 발생
    - 가정으로 인한 안정감 감소

### 낮은 코드 적응력
- 코드 적응령이 낮으면 단위 테스트하기가 매우 어렵다.
- 이미 코드 적응력이 낮은 코드 기반에 테스트 주도 개발을 적용하기 어렵다.
- 코드 기반의 적응력을 높이는 것도 어렵다.
    - 설계 변경의 어려움
    - 변경된 설계 검증 필요

<br/>

## 9. 인터페이스와 테스트

### 인터페이스
- 한 개체가 상호작용하는 다른 개체에 제공하는 상호작용 지점

### API
- Application programming interface
- 한 시스템이 협력 시스템에 제공
- 코드 친화적 소통 수단
- 테스트 자동화 비용이 낮음

### UI
- User interface
- 한 시스템이 시스템 사용자에게 제공
- 인간 친화적 소통 수단
- 변경이 잦음
- 테스트 자동화 비용이 높음


<br/>

## 10. 인수 테스트 주도 개발

### 인수 테스트
- 배치된 코드를 대상으로 최종 클라이언트 관점으로 테스트
- UI 응용프로그램
    - 사용자가 클라이언트
    - 테스트 자동화 작성고 운영 비용이 상대적으로 높음
- API 응용프로그램
    - 외부 시스템이 클라이언트
    - 테스트 자동화 작성과 운영 비용이 상대적으로 낮음


<br/>

## 11. 코딩 계획

### 코딩 작업 설계
- 목표를 명확히 기술
- 작업 분리

### 업무 가시성
- 투명한 작업자의 업무 내용과 진행도
- 위험 요소를 더 빨리 발견할 가능성이 높아짐
