📌 일반적인 TDD 주기
- 테스트를 작성한다.
- 머릿속의 오퍼레이션이 코드에 어떤 식으로 나타나길 원하는가? 이야기를 써내려가라.
- 원하는 인터페이스를 개발하라.
- 올바른 답을 얻기 위해 필요한 이야기의 모든 요소를 포함시켜라.
- 실행 가능하게 만든다.
- 빨리 초록 막대를 보는 것이 중요하다.
- 명백하게 깔끔하고 단순한 해법이 보인다면 그것을 입력하고, 구현을 위해 몇 분 정도 걸릴 거 같다면 일단 초록 막대를 빨리 보는 것에 집중하라.
- 올바르게 만든다.
- 시스템이 작동하므로 직전에 저질렀던 죄악을 수습하라.
- 좁고 올곧은 소프트웨어 정의(software righteousness)의 길로 돌아와 중복을 제거하고 초록 막대로 되돌려라.
작동하는 깔끔한 코드를 얻기 위해 나누어서 정복하자(divide and conquer)
일단 '작동하는'에 해당하는 부분을 해결하고, 그런 다음 '깔끔한 코드' 부분을 해결하라.
📌 Dollar 부작용 해결하기
class DollarTest {
@Test
void testMultiplication() {
Dollar five = new Dollar(5);
five.times(2);
assertEquals(10, five.amount);
}
}
이전의 코드는 무언가 이상하다. times()를 호출한 이후에 five는 더 이상 5가 아니기 때문이다.
times()에서 새로운 객체를 반환하게 만든다면 Dollar 인터페이스를 수정하게 되지만 문제가 해결될 것이다.
어떤 구현이 올바른가에 대한 우리 추측이 완벽하지 못하므로, 올바른 인터페이스에 대한 추측 역시 절대 완벽하지 못하다.
class DollarTest {
@Test
void testMultiplication() {
Dollar five = new Dollar(5);
Dollar product = five.times(2);
assertEquals(10, product.amount);
product = five.times(3);
assertEquals(15, product.amount);
}
}
public class Dollar {
...
public Dollar times(int multiplier) {
return new Dollar(amount * multiplier);
}
}
$5 + 10CHF = $10(환율이 2:1일 경우)$5 * $2 = $10
amount를 private로 만들기Dollar 부작용?
Money 반올림?
우리는 위 과정을 거쳐 3가지를 배우게 되었다.
- 설계상의 결함(Dollar 부작용)을 그 결함으로 인해 실패하는 테스트로 변환
- 스텁 구현으로 빠르게 컴파일이 통과하도록 만들었다.
- 올바르다고 생각하는 코드를 입력해 통과했다.
💡 느낌(부작용에 대한 혐오감)을 테스트로 변환하는 것은 TDD의 일반적인 주제다.
📌 최대한 빠르게 초록색을 보기 위한 전략
- 가짜로 구현하기
- 상수를 반환하게 만들고 진짜 코드를 얻을 때까지 단계적으로 상수를 변수로 바꾸어 간다.
- 예상치 못한 빨간 막대를 만났을 때
- 명백한 구현 사용하기
- 실제 구현을 입력한다.
- 모든 일이 명백하고 무엇을 입력해야 할지 알 때
- 삼각측량(triangulation) - 3장