본문 바로가기

IT Book Summary/TDD

1-3장

들어가며.

 

테스트 주도 개발에는 단순한 두가지 규칙만을 따른다

  • 오직 자동화된 테스트가 실패할 경우에만 새로운 코드를 작성한다.
  • 중복을 제거한다.

 

위의 규칙에 의한 프로그래밍 순서는 다음과 같다.

  1. 빨강- 실패하는 작은 테스트를 작성한다.
  2. 초록- 어찌되었든지간에 테스트를 통과하게 만든다.
  3. 리팩토링- 일단 테스트를 통과하면서 생겨났던 모든 중복을 제거한다.

왜 이런식으로 작업해야할까? 왜 테스트를 위한 추가 작업을 해야만 하는가?

-> 불확실함 보다는 일단 구체적으로 시작해보자.

-> 새로운 설계 결정을 한번에 하나씩 도입하기 위해. 

 

목표는 작동하는 깔끔한 코드를 만드는 것이다.


1장 다중 통화를 지원하는 Money 객체

 

앞으로 어떤일을 해야하는지 알려주고

지금하는일에 집중할 수 있도록 도와주며  

언제 일이 다 끝나는지 알려줄 수 있는 할일 목록을 작성하자.

다른 테스트가 생가가나면 목록에 새롭게 항목을 추가한다.

마치 트렐로 카드 목록과 비슷하다.

 

$5 + 10CHF = $10 (환율이 2:1일 경우)

$5 x 2 = $10

 

객체를 만들면서 시작하는게 아니라 테스트를 먼저 만들어야 한다.

 

첫번째 테스트는 복잡해 보이므로 두번째 것부터 시작.

 

public void testMultiplication() {
    Dollar five = new Dollar(5);
    five.times(2);
    assertEquals(10, five.amount);
}

 

-> 할일목록 업데이트

$5 + 10CHF = $10(환율이 2:1일 경우)

$5 x 2 = $10

amount를 private으로 만들기

Dollar 부작용(side effect)?

Money 반올림?

 

-> 컴파일만 되게 만들어보자

네개의 컴파일 에러

  • Dollar 클래스가 없음
  • 생성자가 없음
  • times(int) 메서드가 없음
  • amount 필드가 없음

테스트는 실패하였다.

-> 일단 이 테스트를 통과시키고 나머지 테스트도 통과하도록 할것이다.

 

테스트 주기는 다음과 같다.

  1. 작은 테스트를 하나 추가한다.
  2. 모든 테스트를 실행해서 테스트가 실패하는 것을 확인하다.
  3. 조금 수정한다.
  4. 모든 테스트를 실행해서 테스트가 성공하는 것을 확인한다.
  5. 중복을 제거하기 위해 리팩토링을 한다.

-> 이제 중복을 제거할 것이다.

TDD의 핵심을 작은 단계를 밟아가야 한다는 것이다.

 

  • 작업해야할 테스트 목록
  • 오퍼레이션이 외부에서 어떻게 보이길 원하는지 코드로 표현
  • JUnit
  • 스텁구현을 통해 테스트 컴파일
  • 일단 테스크 통과시킴
  • 코드에서 상수를 변수로 변경. 점진적으로 일반화
  • 새로운 할일들은 할일목록에 추가하고 넘어감.

 


2장 타락한 객체

 

일반적인 TDD 주기

테스트를 작성한다. 원하는 인터페이스, 필요한 모든 요소를 포함시키자 -> 일단 실행가능하게 만든다. -> 수습하고 올바르게 만든다. 

 

목적은 작동하는 깔끔한 코드를 얻는 것.

: 일단 작동하게 하고 나서 깔끔한 코드 문제를 해결하는 것이다.

Mock객체나 Stub 으로 일단 돌아가게 테스트를 만드는것이 이 개념을 바탕으로 만들어진 것인지? 

 

-> Dollar객체의 값을 변하지 않게 수정하자.

- times() 객체 반환하여 해결.

$5 + 10CHF = $10(환율이 2:1일 경우)

$5 x 2 = $10

amount를 private으로 만들기

Dollar 부작용(side effect)?

Money 반올림?

 

  • 가짜로 구현하기 : 상수를 반환하게 만들고 단계적으로 상수를 변수로 바꿈
  • 명백한 구현 사용하기 : 실제 구현을 입력.

-> 두가지 방법을 번갈아가며 사용.

어떤것을 할지 알때는 명백한 구현은 더해나가다 실패할 경우 가짜 구현을 적절히 섞고 올바른 코드로 리팩토링.

 

 

  • 설계상의 결함으로 실패하는 테스트로 변환
  • 스텁 구현으로 일단 컴파일을 통과
  • 올바른 코드 구현하여 테스트 통과

구체적 사례에 의해서 실패하는 테스트를 만드는것이 좋은 코드를 구현하는 방법

 

 


3장 모두를 위한 평등

 

일반적으로 객체는 우리 예상대로 동작하지 않는다.

 

Dollar 객체처럼 객체를 값처럼 쓸 수 있는 것을 값-객체 패턴 value object pattern 

 

-> 값 객체는 equals()를 구현해야 한다.

Dollar를 해시테이블 키로 쓸 생각이라면 equals()를 구현할 때 hashCode()를 같이 구현해야 함.

$5 + 10CHF = $10(환율이 2:1일 경우)

$5 x 2 = $10

amount를 private으로 만들기

Dollar 부작용(side effect)?

Money 반올림?

equals()

hashCode()

 

-> 값 객체는 새 객체를 반환해야 함

 

public void testEquality() {
    assertTrue(new Dollar(5).equals(new Dollar(5)));
}

//가짜로 구현
public boolean equals(Object object) {
    return true;
}

 

 

유추에 의해 알수있는 삼각측량을 이용

설계를 어떻게 할지 떠오르지 않을 때 삼각측량은 문제를 조금 다른 방향에서 생각해볼 기회를 제공한다.

 

public vlid testEquality() {
    assertTrue(new Dollar(5).equals(new Dollar(5)));
    assertFalse(new Dollar(5).equals(new Dollar(6)));
}

//equality 일반화
public boolean equals(Object object) {
    Dollar dollar = (Dollar) object;
    return amount == dollar.amount;
}

 

-> 동질성 기능은 구현했으므로 Dollar와 Dollar를 직접 비교할 수 있게 됐다.

이제 amount를 private으로 만들 수 있다.

 

  • 값 객체 가 하나의 또 다른 오퍼레이션을 암시한다는걸 알았다.
  • 해당 오퍼레이션을 테스트
  • 해당 오퍼레이션을 간단히 구현
  • 좀 더 테스트
  • 두 경우 모두 수용하도록 리팩토링

 

 

'IT Book Summary > TDD' 카테고리의 다른 글

18장-20장 xUnit  (0) 2020.03.24
13-17장  (0) 2020.03.18
10-12장  (0) 2020.03.10
7-10장  (0) 2020.03.09
4-6장  (0) 2020.03.02