[테스트 주도 개발(TDD) 시작하기] 테스트 코드 작성 순서

·2022년 11월 4일
0
post-thumbnail

테스트 코드 작성 순서

  1. 쉬운 경우 → 어려운 경우
  2. 예외적인 경우 → 정상적인 경우

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

복잡한 것 부터 구현하다보면 한 번에 너무 많은걸 구현해야하게 된다.
짧은 흐름을 가져가기 위해서 구현하기 쉬운 테스트부터 시작하도록 하자.

[암호 측정 예시]

  • 검사할 규칙은 다음 세 가지이다.
    1. 길이가 8글자 이상
    2. 0부터 9 사이의 숫자를 포함
    3. 대문자 포함
  • 세 규칙을 모두 충족하면 암호는 "STRONG"이다.
  • 2개의 규칙을 충족하면 암호는 "NORMAL"이다.
  • 1개 이하의 규칙을 충족하면 암호는 "WEAK"이다.

위와 같은 암호 강도 측정 예에서는
1. 모든 조건을 충족하는 경우
2. 모든 조건을 충족하지 않는 경우
가 가장 쉬운 기능이다.

이 중, 1번(모든 조건을 충족하는 경우)를 가장 먼저 구현했다고 하자.
다음으로는?
1. 모든 규칙을 충족하지 않는 경우
2. 한 규칙만 충족하는 경우
3. 두 규칙을 충족하는 경우
1번은 정반대이기때문에 구현해야할 코드가 많다.
2번은 한 규칙만 통과하면 되고, 3번은 한 규칙만 어기면 된다.
즉 2번과 3번 중 하나를 선택해야한다!
그 중 1번을 택하자.

이렇게 하나의 테스트를 통과했으면 그 다음으로 구현하기 쉬운 테스트를 선택해야 한다.

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

예외 상황은 복잡한 if-else 블록을 동반할 때가 많고, 이를 차후에 반영하려면 코드 구조를 뒤집는 경우가 발생한다.
초반에 예외 상황을 테스트해서 미리 if-else 구조를 잡자.

완급 조절

TDD를 처음 접할 때는 다음 단계에 따라 TDD를 익혀보도록 하자.

  1. 정해진 값을 리턴
  2. 값 비교를 이용해 정해진 값을 리턴
  3. 다양한 테스트를 추가하면서 구현을 일반화

지속적인 리팩토링

  • 코드 중복은 대표적인 리팩토링 대상이다
    • 메서드 추출을 통해 해결하자.
  • 메서드의 파라미터 개수가 세 개 이상이면 객체로 바꿔 한 개로 줄이는 것을 고려하자.
    - 이 때, 빌더 패턴을 이용하면 좋다.

리팩토링 시점

  • 상수 → 변수나, 변수 네이밍 변경 등의 작은 리팩토링은 발견하는 즉시 실행한다.
  • 메서드 추출과 같이 메서드의 구조에 영향을 주는 리팩토링은 큰 틀에서 구현 흐름이 눈에 들어오기 시작한 뒤에 진행한다.

테스트할 목록 정리하기

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);

구현이 막히면

다음 두가지만 항상 상기하자.

  • 쉬운 테스트, 예외적인 테스트
  • 완급 조절

0개의 댓글