The RED : 이규원의 현실 세상의 TDD - 테스트 주도 개발의 깊은 곳
===
###### tags: `석기`
---
## 인터페이스와 구현
#### 추상화
- 목적에 따라서, 대상이 가지고 있는 것들중에 일부만 투영하는 것.
#### 인터페이스
- '무엇'을 표현
- 클라이언트에게 반드시 필요한 정보
- 협력하는 코드 사이의 계약
- 추상화 결과
#### 정보 숨김
- 효과적인 모듈화
- 조직간 의사소통 최소화
- 변경여파 최소화
- 시스템 이해 도움
---
## 환경 변화와 적응력
#### 모듈화
- 모듈화가 잘 된 코는 환경변화에 덜 민감하다.
#### 개체 지향
**OOP 는 late-binding이 특징이다.**
##### ==다형성==
#### 개방 - 폐쇄 원칙
- 확장 가능한 경우 모듈은 열려있다고 한다.
- 다른 모듈에 의해 사용될 수 있을때, 모듈을 닫혀있다고 한다.
==실습==
실습 중 놀라운 코드 발견...
```javascript=
function plus(n) { return n + 1 }
function twice(n){ return n * 2 }
function triple(n) { return n * 3 }
function combineFuncs(functions) {
return (src) => functions.reduce((value, fc) => fc(value), src)
}
const calcuate = combineFuncs([plus, twice, triple])
calcuate(10) // 66
```
- 위의 `combineFuncs` 함수에 인자를 추가하며 필요한 기능을 덧붙여서 리팩토링 할 수 있다.
---
## 입력과 출력
#### 직접 입력, 직접 출력
- 공개된 인터페이스를 통한 입력과 출력
- 다루기 간단.
#### 간접 입력, 간접 출력
- 입력된 인터페이스를 통한 입력과 출력
- 다루기 힘듬.
### 부작용
- 인터페이스 설계에 드러나지 않은 출력
- 실패
- 지연
- 간접출력
---
## 테스트 대역
### 대역과 가정
- DOC 준비 비용이 큰 경우
- 구동에 많은 자원이 필요
- 환경 제어가 어려움
#### Dummy
- SUT 준비를 위해 해결되어야하는 의존성이 테스트 대상 논리에 의해 사용되지 않는 경우에
의존요소를 대신하는 테스트 대역
#### Stub
- 간접 입력 대역
- 미리 준비된 답을 출력
#### Spy
- 간접 출력 대역
- SUT의 간접 출력 기록
---
## Mockists vs Classicsts
#### Socialble 테스트
- 의존 대상까지 테스트
#### Solitary 테스트
- 의존대상을 격리시켜서 테스트 대역을 테스팅하는 기법.
#### 테스트 대역 - 가정의 안정도
**가정을 얼마나 믿을 수 있을까?**
- 테스트 대역이 구현하는 인터페이스가 단순할수록 안정적.
- 데스트 대역이 구현하는 인터페이스가 복잡할수록 불안정적이다.
#### Mock 의 위험
- 정보 숨김 위배
- 테스트가 SUT 구현에 의존하게 됨.
- refactoring 불안 / 고통스럽다.
---
## Should I test private methods
#### Private 메소드를 테스트를 해야하는가?
:::warning
NO
:::
#### 비공개 모듈 테스트
- 비공개 모듈의 작성과 사용은 공개 모듈의 구현 영역.
- 비공개 모듈 테스트는 공개 모듈 구현 노출.
---
## 테스트 주도 설계
#### 설계가 단위 테스트에 미치는 영향
- 테스트는 인터페이스 설계에 의존
- 인터페이스 설계 품질이 낮으면 테스트 작성이 불편
#### 단위 테스트가 설계에 미치는 영향
- 테스트가 있기 때문에 리팩토링 가능
- 구현설계를 과감하게 개선이 두려움이 없음.
#### 단위 테스트에 의지하는 인터페이스 설계
**단위 테스트는**
- 일관된 설계를 강요하지 않는다.
- 낮은 응집에 대한 피드백을 주지 않는다.
- 의도 노출을 요구하지 않는다.
#### 단위 테스트에 의지하는 구현 설계
- 단위 테스트는 책임 분산을 유도하지 않음.
- Mock을 과도하게 사용할 수 있다.
- 코드의 양이 작아지기도 하고
- 구현을 생각하며 테스트 코드를 짜게 된다.
- 비공개 운영 코드 테스트
- private method, internal class가 공개되어버린다.
---
## TDD의 한계
### 은탄환은 없다.
- 도구의 법칙
- 유용하고 매력적인 도구지만 / 남용을 주의하여야한다.
### 불안정한 목표
- 모든 코드의 목표가 안정적이지는 않음
- 테스트 코드 작성 비용 부담이 클 수 있음.
---
## 인터페이스와 테스트
#### 인터페이스
- 한 개체가 상호작용하는 다른 개체에 제공하는 상호작용 지점
- 약속된 계약에 의해 서비스를 제공받을때의 말임.
#### API
- 코드 친화적 소통수단
- 테스트 자동화 비용이 낮음
- 한 시스템이 협력 시스템에 제공.
- 테스트 코드도 이를 사용하여 테스트 진행.
- 기계를 위한것이므로 테스트(사람)은 어려움
#### UI
- 한 시스템이 시스템 사용자에게 제공.
- 인간 친화적 소통 수단.
- 변경이 잦음.
- 테스트 자동화 비용이 높음.
---
## 인수 테스트 주도 개발
### 인수 테스트
- 배치된 코드를 대상으로 최종 클라이언트 관점으로 테스트
- UI 응용 프로그램
- 사용자가 클라이언트
- 테스트 자동화 작성 / 운영 비용이 상대적으로 높음
- API 응용 프로그램
- 외부 시스템이 클라이언트

---
## 코딩 계획
#### 코딩 작업 설계
- 목표를 정확히 기술
- 어떤 가치를 구현?
- 명확한 이정표가 없다면 쉽게 길을 잃는다.
- 사용자 스토리 / 테스트 케이스는 목표 기술의 좋은 수단.
- 작업 분히
- 전체작업을 하위 작업으로 작게 분리
- 하위 작업 역시 목표를 명확히 분리
#### 업무 가시성
- 투명한 작업자의 업무 내용과 진행도 / 위험요소를 더 빨리 발견할 가능성이 높으짐.