Post

테스트 주도 개발 시작하기 리뷰 - 3장

테스트 주도 개발 시작하기 리뷰 - 3장

들어가며

이 포스트는 최범균의 「테스트 주도 개발 시작하기」 3장을 읽고 개인적으로 학습한 내용을 정리한 글입니다.

  • 책: 테스트 주도 개발 시작하기
  • 저자: 최범균
  • 출판사: 가메출판사
  • 챕터: 3장

핵심 개념 요약

3장 테스트 코드 작성 순서

초반에 복잡한 테스트부터 시작하면 안 되는 이유

  • 보통 개발자는 한 번에 많은 코드를 만들다 보면 나도 모르게 버그를 만들고 나중에 버그를 잡기 위해 많은 시간을 사용 => 세트스 통과 시간도 길어짐
  • 코드 작성 시간이 길어지면 집중력도 떨어져서 흐름이 자주 끊김

구현하기 쉬운 테스트부터 시작하기

  • 가장 구현하기 쉬운 경우부터 시작하면 빠르게 테스트를 통과시킬 수 있다
  • 하나의 테스트를 통과하면 그 다음으로 구현하기 쉬운 테스트를 선택

예외 상황을 먼저 테스트해야 하는 이유

  • TDD를 하는 동안 예외 상황을 찾고 테스트에 반영하면 예외 상황을 처리하지 않아 발생하는 버그를 줄여줌

완급 조절

  • TDD를 익히는 스탭
    1. 정해진 값을 리턴
    2. 값 비교를 이용해서 정해진 값을 리턴
    3. 다양한 테스트를 추가하면서 구현을 일반화
  • 테스트를 만들고 통과시키는 과정에서 구현이 막힐 때가 있으나, 위의 단계를 사용하면 조금씩 기능을 구현할 수 있음

지속적인 리팩토링

  • 테스트 통과 후 리팩토링 진행
  • 테스트 대상 코드의 리팩토링 시점
    • 테스트 대상 코드에서 상수를 변수로 변경, 변수 이름 변경 같은 작은 피랙토링은 바로 실행
    • 메서드 추출과 같이 메서드의 구조에 영향을 주는 리팩토링은 큰 틀에서 구현 흐름이 눈에 들어오기 시작한 뒤 진행

쉬운 것부터 테스트

  • 구현하기 쉬운 것부터 먼저 테스트
  • 예외 상황을 먼저 테스트

예를 추가하면서 구현을 일반화

  • 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
void 만원_납부하면_한달_뒤가 만료일이_됨(){
    LocalDate billingDate = LocalDate.of(2019,3,1);
    int payAmount = 10_000;

    ExpiryDateCalculator cal = new ExpiryDateCalculator();
    LocalDate expiryDate = cal.calculateExpiryDate(billingDate, payAmount);

    assertEquals(LocalDate.of(2019,4,1),expiryDate);

    LocalDate billingDate2 = LocalDate.of(2019,5,5);
    int payAmount2 = 10_000;

    ExpiryDateCalculator cal2 = new ExpiryDateCalculator();
    LocalDate expiryDate = cal2.calculateExpiryDate(billingDate2, payAmount2);

    assertEquals(LocalDate.of(2019,4,1),expiryDate2);
}

코드 정리: 중복 제거

1
2
3
4
5
6
private void assertExpiryDate(
    LocalDate billingDate, int payAmount, LocalDate expectedExpireDate){
        ExpiryDateCalculator cal = new ExpiryDateCalculator();
        LocalDate realExpiryDate = cal.calculateExpiryDate(billingDate, payAmount);
        assertEquals(expectedExpireDate, realExpiryDate);
}

예외 상황 처리

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ExpiryDateCalculatorTest {
    @Test
    void 만원_납부하면_한달_뒤가 만료일이_됨(){
        //...
    }

    @Test 
    void 납부일과_한달_뒤_일자가_같지_않음(){
        assertExpiryDate(
            LocalDate.of(2019,1,31), 10_000,
            LocalDate.of(2019,2,28));
    }
}

다음 테스트를 추가하기 전에 리팩토링

테스트할 목록 정리하기

  • TDD 시작 시 테스트 목록을 미리 정리하면 좋음
  • 정리한 테스트 목록 중 가장 구현이 쉬운 테스트 & 예외 테스트 상상 후 테스트 선택
  • 테스트 과정에서 새로운 테스트 사례를 발견하면 그 사례를 목록에 추가
  • 테스트 작성 수를 ‘적당히’
    • 너무 많이 넣으면 구현 초기에도 리팩토링을 마음껏 할 수 없음
    • 모든 테스트 중 계속 테스트가 깨져 개발 리듬이 사라짐

시작이 안 될 때는 단언부터 고민

  • 테스트 코드를 어떻게 작성할 지 감이 잡히지 않는다면 검증 코드부터 시작
This post is licensed under CC BY 4.0 by the author.