[TDD] Test Driven Development

JiKwang Jeong·2022년 5월 10일
0

이 글은 최범균님의 테스트 주도 개발 시작하기라는 책을 참고하였습니다.
http://m.yes24.com/Goods/Detail/89145195

TDD 시작하기

TDD란?

  • TDD는 기능을 검증하는 테스트 코드를 먼저 만든다.
  • 예를 들어 덧셈 기능에서 덧셈 기능을 검증하는 테스트 코드를 먼저 작성한다.
  • 이 과정에서 테스트 대상이 될 클래스 이름, 메서드 이름, 파라미터 개수, 리턴 타입을 고민한다.
  • 새로운 객체를 생성할지 아니면 정적 메서드로 구현할지 고민한다.
  • 테스트 코드 작성 후, 컴파일 오류를 없애는 데 필요한 클래스와 메서드를 작성한다. 그리고 바로 테스트를 진행하고 테스트 실패를 확인한다.
  • 실패한 테스트를 통과시킨 뒤에 새로운 테스트를 추가하고 그 테스트를 통과시키기 위한 코드를 작성한다.
  • 즉,테스트를 먼저 작성하고 테스트에 실패하면 테스트를 통과시킬 만큼 코드를 추가하는 과정을 반복하면서 점진적으로 기능을 완성한다.

TDD 흐름

테스트 -> 코딩 -> 리팩토링의 반복

  • TDD는 기능을 검증하는 테스트를 먼저 작성
  • 작성한 테스트를 통과하지 못하면 테스트를 통과할 만큼만 코드를 작성
  • 테스트를 통과한 뒤 개선할 코드가 있으면 리팩토링
  • 리팩토링 수행 후 다시 테스트를 실행해서 기존 기능이 망가지지 않았는지 확인
  • 이 과정을 반복하면서 점직적으로 기능을 완성해 나가는 것이 전형적인 TDD의 흐름이다.

레드-그린-리팩터
TDD 사이클은 레드(Red)-그린(Green)-리팩터(Refactor)로 부르기도 한다. 여기서 레드는 실패하는 테스트를 의미한다. 레드는 테스트 코드가 실패하면 빨간색을 이용해서 실패한 테스트를 보여주는 데서 비롯했다. 비슷하게 그린은 성공한 테스트를 의미한다. 즉 코드를 구현해서 실패하는 테스트를 통과시키는 것을 뜻한다. 마지막으로 리팩터는 이름 그대로 리팩토링 과정을 의미한다.

테스트 코드 작성 순서

  1. 초반에 복잡한 테스트부터 시작하지 않는다.
    초반부터 다양한 조합을 검사하는 복잡한 상황을 테스트로 추가하면 해당 테스트를 통과시키기 위해 한 번에 구현해야 할 코드가 많아진다.

  2. 구현하기 쉬운 테스트부터 시작한다.
    보통 수 분에서 십여 분 이내에 구현을 완료해서 테스트를 통과시킬 수 있을 만큼 쉬운 것을 선택한다.
    작성한 코드가 많지 않고 시간이 짧으면 내용이 생생하게 남아 있으므로 디버깅할 때 문제 원인을 빠르게 찾을 수 있다.

  3. 예외 상황을 먼저 테스트한다.
    초반에 예외 상황을 테스트하면 코드 중간에 예외 상황을 처리하기 위해 조건문을 중복해서 추가하는 일이 줄어든다.

  4. 완급 조절
    처음 TDD를 접할 때면 다음 단계에 따라 TDD를 작성해본다.

    1. 정해진 값을 리턴
    2. 값 비교를 이용해서 정해진 값을 리턴
    3. 다양한 테스트를 추가하면서 구현을 일반화
  5. 지속적인 리팩토링
    코드 중복은 대표적인 리팩토링 대상이다. 코드가 길어지면 메서드 추출과 같은 기법을 사용해서 메서드 이름으로 코드의 의미를 표현할 수 있다.
    지속적인 리팩토링은 코드 가독성을 높여준다. 이로 인해 수정 요청이 있을 때 변경할 코드를 빠르게 찾을 수 있다. 이는 코드 변경의 어려움을 줄여주어 향후 유지보수에 도움이 된다.

테스트할 목록 정리

  • 먼저 테스트할 내용을 정리했다면 이 중에 어떤 테스트가 구현이 쉬울지 상상한다. 또는 어떤 테스트가 예외적인지 상상한다.
  • 테스트 과정에서 새로운 테스트 사례를 발견하면 그 사례를 목록에추가해서 놓치지 않도록 한다.
  • 테스트 목록을 적었다고 해서 테스트를 한 번에 다 작성하면 안 된다. 한 번에 작성한 테스트 코드가 많으면 구현 초기에 리팩토링이 힘들어진다.
  • 하나의 테스트 코드를 만들고 이를 통과시키고 리팩토링하고 다음 테스트 코드를 만들고 통과시키고 리팩토링하는 과정을 비교적 짧은 리듬으로 반복한다.
    (개발 집중력을 높이기 위해서)

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

  • 테스트 코드의 시작이 잘 안될 경우는 검증하는 코드부터 작성하기 시작하는 것이 도움이 된다.
  • 마지막으로 구현이 막히면 과감하게 코드를 지우고 미련 없이 다시 시작한다.
    어떤 순서로 테스트 코드를 작성했는지 돌이켜보고 순서를 바꿔서 다시 진행한다. 다시 진행할 때에는 다음을 상기한다.
    • 쉬운 테스트, 예외적인 테스트
    • 완급 조절

TDD, 기능 명세, 설계

기능 명세

  • 설계는 기능 명세로부터 시작한다. 스토리보드를 포함한 다양한 형태의 요구사항 문서를 이용해서 기능 명세를 구체화한다.
  • 기능 명세를 구체화하는 동안 입력과 결과를 도출하고 이렇게 도출한 기능 명세를 코드에 반영한다.
  • 기능 명세의 입력과 결과를 코드에 반영하는 과정에서 기능의 이름, 파라미터, 리턴 타입 등이 결정된다.

필요한 만큼 설계

  • TDD는 테스트를 통과할 만큼만 코드를 작성한다. 필요할 것으로 예측해서 미리 코드를 만들지 않는다.
  • 실제 테스트 사례를 추가하고 통과시키는 과정에서 필요한 만큼 설계를 변경한다.

기능 명세 구체화

  • 테스트 코드를 작성하려면 파라미터와 결과 값을 정해야 하므로 개발자는 요구사항 문서에서 기능의 입력과 결과를 도출해야 한다. 또한, 다양한 테스트 사례를 추가하는 과정에서 구현하기 애매한 점을 발견하게 된다.
profile
기억보다 기록, 난리보다 정리

0개의 댓글