- 쉬운 경우 → 어려운 경우
- 예외적인 경우 → 정상적인 경우
복잡한 것 부터 구현하다보면 한 번에 너무 많은걸 구현해야하게 된다.
짧은 흐름을 가져가기 위해서 구현하기 쉬운 테스트부터 시작하도록 하자.
[암호 측정 예시]
- 검사할 규칙은 다음 세 가지이다.
- 길이가 8글자 이상
- 0부터 9 사이의 숫자를 포함
- 대문자 포함
- 세 규칙을 모두 충족하면 암호는 "STRONG"이다.
- 2개의 규칙을 충족하면 암호는 "NORMAL"이다.
- 1개 이하의 규칙을 충족하면 암호는 "WEAK"이다.
위와 같은 암호 강도 측정 예에서는
1. 모든 조건을 충족하는 경우
2. 모든 조건을 충족하지 않는 경우
가 가장 쉬운 기능이다.
이 중, 1번(모든 조건을 충족하는 경우)를 가장 먼저 구현했다고 하자.
다음으로는?
1. 모든 규칙을 충족하지 않는 경우
2. 한 규칙만 충족하는 경우
3. 두 규칙을 충족하는 경우
1번은 정반대이기때문에 구현해야할 코드가 많다.
2번은 한 규칙만 통과하면 되고, 3번은 한 규칙만 어기면 된다.
즉 2번과 3번 중 하나를 선택해야한다!
그 중 1번을 택하자.
이렇게 하나의 테스트를 통과했으면 그 다음으로 구현하기 쉬운 테스트를 선택해야 한다.
예외 상황은 복잡한 if-else 블록을 동반할 때가 많고, 이를 차후에 반영하려면 코드 구조를 뒤집는 경우가 발생한다.
초반에 예외 상황을 테스트해서 미리 if-else 구조를 잡자.
TDD를 처음 접할 때는 다음 단계에 따라 TDD를 익혀보도록 하자.
- 정해진 값을 리턴
- 값 비교를 이용해 정해진 값을 리턴
- 다양한 테스트를 추가하면서 구현을 일반화
TDD를 싲가할 때 테스트할 목록을 미리 정리하도록 하자.
그리고 그 목록을 보며, 어떤 테스트가 구현이 쉬울지 / 어떤 테스트가 예외적인지 상상해보고 다음 테스트를 선택하자.
테스트 과정에서 새로운 테스트 케이스를 발견하면 그 케이스를 목록에 추가해서 놓치지 않도록 하자.
테스트 목록응ㄹ 작성했다고 테스트를 한번에 다 작성하면 안된다.
하나의 테스트 코드를 만들고 통과시키고 리팩토링하고, 다시 다음 테스트 코드를 만들고 통과시키고 리팩토링 하는 과정은 비교적 짧은 리듬을 반복하자.
테스트 코드 작성 시작이 잘 안될 땐, 검증 코드부터 작성하기 시작하자.
// [1]
assertEquals(기대하는만료일, 실제만료일);
// [2]
assertEquals(LocalDate.of(2019,8,9), 실제만료일);
// [3]
LocalDate realExpiryDate = 계산하기
assertEquals(LocalDate.of(2019,8,9), realExpiryDate);
// [4]
LocalDate realExpiryDate = cal.calculateExpiryDate(파라미터);
assertEquals(LocalDate.of(2019,8,9), realExpiryDate);
// [5] cal의 타입과 파라미터 타입 결정
ExpiryDateCalculator cal = new ExpiryDateCalculator();
LocalDate realExpiryDate = cal.calculateExpiryDate(LocalDate.of(2019,7,9), 10_000);
assertEquals(LocalDate.of(2019,8,9), realExpiryDate);
다음 두가지만 항상 상기하자.
- 쉬운 테스트, 예외적인 테스트
- 완급 조절