[TDD] 0. TDD란 무엇인가?

아홉번째태양·2023년 6월 20일
0

TDD

목록 보기
1/4

1. TDD란?

TDD란 Test Driven Development의 약자로서, 테스트 중심의 개발 프로세스를 통해 개발한 서비스 코드의 신뢰성과 안정성을 높히는 개발 패러다임의 일종이다. 서비스 코드의 작성보다 서비스의 시나리오들을 먼저 작성하고, 이를 위한 테스트 케이스들을 상정하며, 그리고 테스트 코드를 먼저 작성하고 테스트에 부합하는 서비스 코드를 나중에 작성하는 방식이다.

2. 왜 TDD를 하는가?

테스트에 대한 특별한 팀 컨밴션이 존재하거나, 아니면 TDD 혹은 그와 유사한 방식의 개발 패러다임을 적용하는 것이 아니라면 보통 테스트 코드는 서비스 코드를 먼저 작성하고 난 이후에 서비스 코드가 의도한대로 동작하는지 확인하기 위해 작성한다. 하지만 이렇게 테스트 코드를 나중에 작성하는 방식에는 몇 가지 문제가 있다.

  1. 테스트를 작성하기가 어렵다
    테스트를 위해 작성한 코드가 아니기 때문에 무엇을 어떻게 테스트할지 서비스 코드가 애매할 수 있다.

  2. 한정되고 편향된 테스트 케이스를 가진다
    이미 완성한 코드의 커버리지를 올리기 위한 테스트 코드 작성이 되어, 서비스 코드에서 다루고 있지 않은 예외 상황들에 대해 생각을 해내기가 쉽지 않아진다.

  3. 그리고 지루하고 재미없다
    처음부터 테스트 코드를 쓰기 좋아하는 사람은 없다. 이미 구현한 기능을 다시 더 많은 코드를 써서 구현하는 것과 같기에, 테스트를 나중에 한다는 것은 이미 완성한 결과를 다시 만드는 지루한 반복과정이 된다.

서비스가 커질수록 기능 하나 추가하고나서 엉뚱한 곳에서 에러가 발생하는 경우들이 계속 생겨나는데, 이때 테스트 코드를 잘 짜서 갖춰두었다면 다를까하는 생각을 하게 된다. 하지만 이미 작성한 코드를 똑같이 작성하는 것이나 다름 없는 테스트 코드 작성은 상당한 거부감이 따른다.

하지만 누구나 어떤 기능을 구현할 때는, 클라이언트 혹은 어떤 문제의 요구사항에 따라 어떤 기능을 어떻게 만들지 구상하고 정리하기 마련이다. TDD는 개발 전 이런 궁리 과정에 테스트 코드 작성을 포함하여 서비스가 완성되었을 때 이미 모든 서비스 로직에 대한 테스트가 이루어지고 있을뿐만 아니라, 서비스 코드의 목적성이 명확해지고 읽기 쉬운 Clean Coding이 부수적으로 따라온다.

3. TDD의 장점

코드의 목적성이 강해진다

테스트는 언제나 목적을 가진다. 그렇기 때문에 어떤 목적을 이루기 위한 객체나 함수 중심으로 코드가 짜여지며 자연스럽게 객체지향프로그래밍 혹은 함수지향프로그래밍 같은 개발 패러다임을 따라가게 된다. 결과적으로 TDD로 개발한 코드는 DRY하고 보편적인 Clean Code원칙을 따르는 형태가 된다.

코드 변경이 쉬워진다

TDD에서 새로운 기능을 추가할 때도 먼저 테스트 코드를 새로 작성하는 것으로 시작한다. 그리고 이를 충족하기 위한 코드만을 구현하면되며, 이때 기존 나머지 테스트들이 여전히 통과하는지 확인이 가능하기 때문에 보다 자신감 있게 새로운 기능을 추가하거나 기존 코드를 수정할 수 있다.

개발시간이 단축된다

이처럼 개발중인 코드에 대한 자신감 덕분에 개발시간이 오히려 단축된다. TDD는 서비스와 각 기능들의 목적에 대해 개발자의 의도가 분명해지고, 설령 문제가 생겨도 어디에 어떻게 문제가 생긴것인지 디버깅이 간단하다.

서비스가 문서화된다

그리고 TDD에 따라 서비스를 설계하는 과정에서 기능명세서, 유저 시나리오, 예상되는 예외 상황들 등에 대한 논의와 문서화가 이루어지기 때문에 서비스에 대해 자세한 설명을 담은 문서가 남는다. 따라서, 서비스를 완성한 이후 문서화를 위해 부가적인 리소스를 사용하지 않아도 된다.

4. TDD의 단점

하지만 TDD가 마냥 만능인 것만은 아니다.

러닝 커브

어떤 새로운 패러다임을 적용한다는 것은 이를 이해하고 체득하는 시간이 필요하다. 또, TDD는 어디까지나 방법론이기 때문에 실제 프로세스는 팀마다 프로젝트마다 조금씩 다를 수 있다. 이는 새로 합류하는 팀원이 서비스 코드와 다양한 코드 컨밴션 외에도 추가로 적응해야하는 규칙이 있음을 의미한다.

초기 세팅 시간

비록 안정화가 되고나면 개발 시간이 단축될 수 있지만, 처음 프로젝트를 세팅하고 설계할때는 오히려 더 많은 시간이 들 수 있다.

테스트 퀄리티

TDD의 장점들이 효력을 발휘하기 위해서는 테스트의 퀄리티가 보장되어야만 한다. 특히, TDD를 처음 접할 때는 단순히 커버리지를 높히기 위해 테스트가 무엇을 테스트하기 위한 것인지 망각하거나 뒤로한채 단순히 테스트 케이스의 개수를 늘리는데 급급하기 쉽다.

따라서 좋은 테스트 코드를 짜기 위해서 그만큼 개발자 개개인이 많은 경험과 공부를 해야한다.

테스트에 대한 주객전도

테스트는 서비스 코드의 품질과 안정성을 보증하기 위한 수단이다. 때문에 테스트 코드의 품질과는 별개로 서비스 코드도 역시 가독성이 좋고, 효율적인 코드를 만들어야 한다. 따라서, TDD를 진행하면서 수시로 더 나은 방법으로 리팩토링이 가능할지에 대해 끊임없이 고민해야한다.

5. TDD 방법

1. 서비스의 요구사항을 확인한다

내가 구현해야하는 서비스가 무엇인지 그 목적을 명확히 하기 위해서는 먼저 요구사항을 면밀하게 확인해야한다.

예를들어, "사용자 회원가입이 필요하다"라는 요구사항이 있다고 가정하고 다음의 내용을을 살펴보자.

2. 이용 시나리오를 구상한다

요구사항에 따라 사용자들의 use case를 구상하고 분석한다.

회원가입을 하려는 사용자는,

  • 회원가입에 필요한 정보들을 입력할 것이고,
  • 회원가입을 요청할 때 이 정보들을 서버에 보낼 것이다.

3. 테스트 케이스를 구체화한다

앞서서 분석한 use case들을 검증하기 위한 테스트 케이스들을 구체화하고 정리한다. 이때, 각각의 테스트 케이스는 더 세부적인 테스트로 더 이상 쪼갤 수 없을 때까지 쪼개고 나누어야 한다.

우선,

  • 입력한 정보들이 올바른지 확인을 하고,
  • 회원 정보가 생성이 되었는지 확인해야한다.

이때, 입력한 각각의 정보들이 내부 정책에서 정한 규칙에 부합하는지 세부적으로 테스트를 해야하고, 회원 데이터를 생성하기 전에 비밀번호 등은 암호화가 되었는지 확인을 미리 해야할 것이다.

4. 가장 작은 단위부터 테스트한다.

TDD는 Bottom-to-Top으로 개발을 진행한다. 테스트 케이스를 통해 구분한 가장 작은 단위부터 개발을하고, 이 단위들이 모여 이룬 로직을 테스트하고, 다시 전체 기능을 테스트하는 식의 피라미드 형태가 되어야 한다.

이렇게 함으로서 최종적으로 완성된 기능의 각 부분이 문제가 없음을 보장할 수 있다.




다음 장에서는 테스트 코드 작성을 위한 사전 단계들에 대해 조금 더 구체적으로 알아보고, 그 이후에 단위 테스트 > 통합 테스트 > e2e 테스트를 TDD 프로세스에 따라 개발을 해보겠다.

0개의 댓글