TDD (Test Driven Development, 테스트 주도 개발)

박영준·2023년 8월 17일
0

CS

목록 보기
4/16

TDD 에 대한 설명은 개발자 면접에서 자주 나오는 질문 중의 하나!

1. 정의

  • 반복 테스트를 이용한 소프트웨어 방법론

    • 짧은 개발 주기의 반복에 의존하는 개발 프로세스
  • 작은 단위의 테스트 케이스를 작성하고, 이를 통과하는 코드를 추가하는 단계를 반복하여 구현

  • 애자일 방법론 중 하나인 eXtream Programming(XP)의 'Test-First' 개념에 기반을 둔 단순한 설계를 중시

  • 단, 실무에 TTD 를 적용하는 것은 업무 환경에 따라 요구되지 않을 수도 있다!

애자일 방법론

지속적으로 피드백을 반영할 수 있는 방법

eXtream Programming(XP)
미래에 대한 예측을 최대한 하지 않고, 지속적으로 프로토타입을 완성하는 애자일 방법론 중 하나.
추가 요구사항이 생기더라도, 실시간으로 반영할 수 있다.

JUnit

  • TDD의 대표적인 Tool
  • 전 세계적으로 가장 널리 사용되는 'Java 단위 테스트 프레임워크'

2. TDD 개발주기

1) TTD 절차 (개발주기)

RED : 테스트 작성 단계

  • 아직 구현되지 않는 기능에 대한 테스트를 작성

    • 단, 해당 테스트는 아직 구현되지 않은 기능에 대한 것이기 때문에 현재 단계에서는 실패하는 것이 당연하다.
  • 주의!
    실패하는 테스트 코드를 작성할 때까지 실제 코드를 '작성하지 않아야' 한다.

GREEN : 구현 단계

  • 주의!
    실패하는 테스트를 통과할 정도의 '최소 실제 코드'를 작성해야 한다.

REFACTOR : 리팩토링 단계

  • 테스트가 실패하지 않는 한, 계속해서 리팩토링을 반복

2) TTD 의 세부 흐름

예시

생년월일(input)을 입력받으면 현재 나이(output)를 출력하는 프로그램

  1. 간단한 것으로 목표를 정한다.

    • 2015, 2018 -> (만)3살 우선 이것을 만들겠다는 생각을 한다.
  2. 만들기 전, 만든 후에 무엇을 테스트할지를 설계

    • 2015, 2018를 입력하면 2가 나오는 테스트 프로그램(장차 만들 프로그램을 테스트할 코드)를 만든다.
    • 단, 실패하는 테스트이어야 한다.
  3. 테스트를 통과할 프로그램(1.을 목표로 작성한 코드)를 만든다.

    • 2018 - 2015 (올해의 연도 - 태어난 해)
  4. 테스트 프로그램으로 이 프로그램(3.에 해당하는 코드)을 실행한다.

  5. 통과했으면 새로운 테스트를 추가

    • 생월을 추가했을 때 계산하는 프로그램
  6. 위의 작업들을 계속 왔다갔다 수행

3. 일반 개발 방식 vs TDD 개발 방식

1) 일반 개발 방식

(1) 개발 주기

  • 요구사항 분석 → 설계 → 개발 → 테스트 → 배포

(2) 단점

소프트웨어 개발을 느리게 하는 잠재적 위험이 존재한다.

  • 소비자의 요구사항이 처음부터 명확하지 않을 수 있다.

    • 일반적으로 고객의 요구사항 등... 의 의해 점진적으로 설계를 완성해가는데, 재설계 과정에서 불필요한 코드 or 중복 코드의 가능성 大
  • 자체 버그 검출 능력 저하 or 소스코드의 품질이 저하될 수 있다.

    • 작은 부분의 기능 수정에도 모든 부분을 테스트해야 하므로, 전체적인 버그를 검출하기 어려워진다.
    • 어디서 버그가 발생할지 모르기 때문에, 잘못된 코드도 고치지 않으려하는 현상이 나타나고, 이 현상은 소스코드의 품질 저하과 직결된다.
  • 자체 테스트 비용이 증가할 수 있다.

    • 작은 수정에도 모든 기능을 다시 테스트해야 하는 문제가 발생하여 자체 테스트 비용이 증가된다.

2) TDD 개발 방식

  • 디자인(설계) 단계에서 프로그래밍 목적을 반드시 미리 정의해야 한다.

  • 무엇을 테스트해야 할지 미리 정의(테스트 케이스 작성)해야만 한다.

  • 테스트 코드를 작성한 뒤에 실제 코드를 작성

  • 테스트 코드를 작성하는 도중에 발생하는 예외 사항(버그, 수정사항)들은 테스트 케이스에 추가하고 설계를 개선한다.

  • 이후 테스트가 통과된 코드만을 코드 개발 단계에서 실제 코드로 작성한다.

4. 장단점

장점

  1. 디버깅 시간 단축

    • 이는 유닛 테스팅을 하는 이점이기도 하다.

    • 사용자의 데이터가 잘못 나온다면

      • 일반 개발 방식 : DB의 문제인지, 비즈니스 레이어의 문제인지 UI의 문제인지 실제 모든 레이러들을 전부 디버깅 해야 한다.
      • TDD : 자동화 된 유닛테스팅을 전제하므로 특정 버그를 손 쉽게 찾아낼 수 있다.
  2. 재설계 시간을 단축

    • 테스트 코드를 먼저 작성하기 때문에, 개발자가 지금 무엇을 해야하는지 분명히 정의하고 개발을 시작하게 된다.
    • 테스트 시나리오를 작성하면서, 다양한 예외사항에 대해 생각해 볼 수 있다.
    • 따라서, 개발 진행 중 소프트웨어의 전반적인 설계가 변경되는 일을 방지할 수 있다.
  3. 작성한 코드가 가지는 불안정성을 개선하여 생산성 향상

    • TDD : 코드가 내 손을 떠나 사용자에게 도달하기 전에 문제가 없는지 먼저 진단 받을 수 있다.
      • 따라서, 코드가 지닌 불안정성과 불확실성을 지속적으로 해소해준다.
  4. 코드가 내 손을 벗어나기 전에 가장 빠르게 피드백 받을 수 있다.

    • 일반 개발 방식 : 90% 이상 완성된 코드를 가지고 테스트하기 때문에, 문제를 발견해도 정확하게 원인이 무엇인지 진단하기는 힘들다.

    • TDD : 기능 단위로 테스트를 진행하기 때문에, 코드가 모두 완성되어 프로그래머의 손을 떠나기 전에 피드백을 받는 것이 가능하다.

  5. 추가 구현이 용이

    • 일반 개발 방식 : 개발이 완료된 소프트웨어에 어떤 기능을 추가할 때, 해당 기능이 기존 코드에 어떤 영향을 미칠지 알지 못한다.
    • TDD : 자동화된 유닛 테스팅을 전제하므로 테스트 기간을 획기적으로 단축시킬 수 있다.

단점

이러한 TDD의 장점에도 불구하고 모두가 이 개발 프로세스를 따르지 않는다.

  1. 생산성의 저하 (느린 개발 속도)

    • 처음부터 2개의 코드를 짜야한다.
    • 중간중간 테스트를 하면서 고쳐나가야 한다.
    • SI 프로젝트에서는 소프트웨어의 품질보다 납기일 준수가 훨씬 중요하기 때문에 TDD 방식을 잘 사용하지 않는다.
  2. 이제까지 자신이 개발하던 방식을 많이 바꿔야 한다.

  3. 구조에 얽매힌다.

    • 원칙을 깰 수는 없고 꼼수가 있기는 한데 그 꼼수를 위해서 구조를 바꾸자니 이건 아무래도 아닌 것 같고,
      테스트는 말 그대로 테스트일 뿐 실제 코드가 더 중요한 상황인데도 불구하고 테스트 원칙 때문에 쉽게 넘어가지 못하는 경우

참고: TDD 방법론 (테스트 주도 개발) - 알기 쉽게 정리
참고: 애자일과 워터폴 방법론 비교 | 정의, 차이, 장단점, 적합한 조직

profile
개발자로 거듭나기!

0개의 댓글