Web Frontend

TDD, DDD, BDD란

이타심 2022. 7. 27. 18:40
728x90
TDD, DDD

# 시작하며

요즘 개발자들 사이에서 주로 사용하는 언어들을 보면, TDD와 DDD로 개발을 진행한다라는 말를 쉽게 들어볼 수 있다. 다소 생소할 수도 있는 해당 용어는 어떠한 의미를 가지고 있을까?

 

* 단위 테스트 - 시스템의 각 구성요소가 올바르게 연동되는지 확인

* 통합 테스트 - 개별 코드나 컴포넌트가 기대한 대로 동작하는지 확인

해당 TDD 서비스가 바탕을 두고 있는 것은 바로 단위 테스트이다. 해당 단위 테스트(Unit Test)는 코드 수정 및 기능 추가 시 빠른 검증이 가능하고, 리팩토링의 안정성을 확보할 수 있다. 또한 개발 및 테스팅에 대한 시간과 비용 역시 절감할 수 있다는 장점이 있다. 모든 서비스가 출시를 위해 애플리케이션을 실행하고, 검증하는 내부 테스트를 진행하는데, 이때 단위 테스트를 작성하지 않은 코드는 버그가 있을 확률이 높고 부가적인 시간과 비용이 발생할 수 있다.

 

 

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

TDD, 즉 테스트 주도 개발 방법론은 짧은 개발 서클을 반복하는 소프트웨어 개발 프로세스로, 소스코드를 작성하기 전에 테스트 케이스를 먼저 작성하는 순서로 개발을 진행한다. 요구사항에 따른 테스트 케이스를 설정하고, 이를 통과할 수 있는 짧은 코드를 작성한다. 그리하여 해당 코드를 리팩토링하는 과정으로 프로그래밍을 진행하는 방법이다. 

 

테스트 코드를 프로덕션 코드보다 먼저 작성하는 이유는 보다 깔끔한 코드 작성과 장기적인 개발 비용 절감에 있으며, 무엇보다 개발에 실패 케이스가 발생할 수 있고 완료된 후 테스트 코드를 작성하는 것 역시 귀찮은 일이기 때문이다. 따라서 TDD의 궁극적인 목표는 작동하는 깔끔한 코드를 작성하는 데 있다. 앞서 언급했듯이, TDD에는 리팩토링 과정이 있는데 해당 과정에서 코드가 중복이 제거되고 깔끔하게 정리된다. 정리하면

  • 개발 비용 절감 및 깔끔한 코드 작성
  • 새로운 기능 추가 시 기존 기능들과 성능 평가
  • 개발에 앞서 테스트를 먼저 작성함으로써, 작동해야할 기능에 대한 고려

등의 이유로 TDD 방법론을 사용하여 개발을 진행한다. 단순히 생각해도 '테스트 코드 작성 >> 기능 구현 코드 작성 >> 리팩토링'의 단계를 반복하기 때문에 코드 퀄리티가 높아질 수밖에 없는 것이다. 또한 짧은 간격으로 기능 구현 및 리팩토링을 반복하기 때문에 더욱 그러하다.

 

* coding convention - 내가 작성한 코드를 다른 사람이 쉽게 이해할 수 있도록 가독성 있는 코드를 작성하는 규칙

개발자로서 프로그램을 작성할 때, 기능 구현과 함께 고려해야 하는 것은 가독성을 위한 *coding convention, 즉 앞으로 서비스 확장에 따른 유지보수를 고려해야 한다. 이를 위해 리팩토링과 테스팅이 필수적인데, 해당 과정에서 발생하는 기능에 대한 오류와 이미 생성된 객체에 대한 네이밍 등에 대한 어려움을 TDD 방법론에서 이미 작성한 테스트 코드로 인해 안정적인 리팩토링을 진행할 수 있는 것이다.

 

<테스트 주도 개발 (Test-Driven Development, TDD) 방법 및 순서>

*쉬운 경우에서 어려운 경우로 진행

* 예외적인 경우에서 정상적인 경우로 진행

  1. 작은 단위의 테스트 작성 
  2. 빠른 테스트 통과를 위해 프로덕션 코드 작성
  3. 테스트 코드 작성
  4. 새로운 테스트 코드 통과를 위한 프로덕션 코드 추가 및 수정
  5. 1~4단계를 반복하여 실패/성공 케이스 작성
  6. 개발 코드에 대한 중복을 제거하며 리팩토링

 

<TDD 접근 방법>

  • 빠른 테스트 통과를 위한 가짜 정답을 구현
  • 값이 다른 여러 테스트를 작성하고 이를 일반화하여 정답 구현하는 삼각층량법
  • 정답을 바로 구현

 


빠른 통과를 위한 가짜 정답 구현


int multiply = (int a, int b) => {
  return 6;
}

void main(){
  int result = mutiply(2,3);
  
  printf(result == 6);
}

가장 빠르게 실패하는 테스트를 구현하는 방법은, 실제가 아닌 상수 등의 임의 값을 반환하는 것이다. 그리고 테스트를 통과하면 단계적으로 작성했던 상수를 변수로 변형한다. 위 코드에서도 연산을 하지 않고 바로 6을 반환하였다. 이렇게 상수를 반환하며 정답이 아닌 방법으로 가짜 구현을 하여 빨리 테스트 통과를 하는 것이 가짜 구현 방법이다. 해당 방법으로 연습을 많이 해두면, 복잡한 코드에서 단계를 잘 나누어 TDD로 문제없이 개발하는 능력을 기를 수 있다. 또한 하나의 잘못된 예시에서 일반화를 함으로써 불필요한 고민으로 혼동되는 일을 예방할 수 있다.

 

 


삼각 측량

삼각 측량은 테스트 주도로 추상화된 과정을 일반화하는 과정이다. 이러한 방법은 테스트 예시가 2개 이상인 경우에만 진행해야 한다.

void test(){

  int result_1 = multiply(2,3);
  int result_2 = multiply(4,7);  
  
  printf(result_1 == 6);
  printf(result_2 == 28);  
  
}

 

 


정답을 바로 구현

정답을 바로 구현하는 것은 가짜 구현이나 삼각 측량을 사용하지 않는다. 

int multiply(int a, int b){
  return a * b;
}

 

 

  • TDD의 단점

그렇다면 이러한 TDD 방법론에 대한 단점에는 무엇이 있을까?

 

- 먼저 코드 생산성의 문제가 있다.

테스트 코드의 작성으로 절대적인 코드량이 늘어나고, 기본적 기능 구현 외에 추가적인 테스트 코드 작성을 해야 하기 때문에 total 프로젝트 시간이 길어지게 된다. 또한 개발이 점차 진행됨에 따라, 비례하여 증가하는 테스트 코드들의 관리에 대한 부분도 이슈가 될 수 있다. 따라서 일정이 촉박하거나 시간적 여유가 없는 프로젝트에는 TDD 적용이 다소 어려울 수 있다.

 

- 테스트 코드 작성의 진입장벽

어떠한 코드를 테스트하기 위해서는 테스트 코드를 작성해야 한다. 하지만 이를 위해서는 소프트웨어에 대한 높은 이해도가 필요하다. 테스트 대상이 되는 기능을 어떠한 방법으로 검증할지, 어떤 프레임워크와 툴을 사용할지에 대한 고민이 필요한 것이다. 

 

- 테스트 코드 작성의 고민

테스트 코드를 작성하기 위한 배경 지식도 중요하지만, 어디서부터 어디까지 테스트 코드를 작성해야 할지 결정하는 것도 문제가 될 수 있다. 테스트 코드 작성을 위해 프로덕트 코드 구조에도 수정을 해야 할 수 있기 때문에, 모든 소스 코드 기능에 대해 테스트를 진행할 수 없다는 고민이 있다.

 

 

 

# BDD(Behavior-Driven Development) - 행위 주도 개발

BDD 방법론은 TDD에서 파생된 프로그래밍 개발 프로세스로서, Buisiness와 end-user의 관점에서 개발을 진행하는 방법이다. TDD에서 테스트가 각 기능에 대한 단위 테스트를 작성했다면, BDD는 통합 테스트와 시나리오 테스트까지 확장하여 진행한다.

 

 


# DDD(Domain-Driven Design) - 도메인 주도 설계

DDD 방법론은, 각 비즈니스의 도메인 패턴을 중심에 놓고 설계하는 방식을 말한다. 도메인 그 자체와 로직에 초점을 맞추어, 데이터 중심의 접근법을 탈피하고 순수한 도메인의 모델과 로직에만 집중한다. 소프트웨어 엔티티와 도메인 컨셉을 가능한 가장 일치시키는 것으로, 분석 모델과 설계 및 코드가 다른 구조가 아니라 도메인 모델부터 코드까지 항상 함께 움직이는 구조의 모델을 지향하는 것이 DDD의 핵심 원리이다.

728x90

'Web Frontend' 카테고리의 다른 글

React SPA란?  (0) 2022.07.29
Tailwind CSS  (0) 2022.07.28
React JSX  (0) 2022.07.26
React  (0) 2022.07.15
React Hooks  (0) 2022.07.14