All Articles

Test-Driven Development(TDD), Behaviour-Driven Development(BDD), Domain-Driven Development(DDD)

개발 방법론 중 일부인 TDD, BDD, DDD가 무엇인지 알아봤다. 개발 경력도 짧고 실제 현장을 아직 경험해보지 못했으므로 어떠한 방법론도 제대로 적용한 적이 없다. 아직은 상상만으로 유니콘을 알아가야 하는 상황과 다름없어 제대로 이해한 부분이 많지는 않다. 특히 DDD는 다른 방법론에 비해 추상적이라서 내가 이해한 것을 내 언어로 바꾸는 것이 더 어려웠다. 하지만 공부한 것을 기록하고 곱씹고 싶어서 글을 작성한다.

Test-Driven Development(TDD)

TDD란

테스트 주도 개발. TDD 방법론에서는 Unit test 같은 테스트 코드를 먼저 작성 후, 테스트를 통과하는 코드를 짠다. 작은 단위로 코드를 작성하는 것으로 시작해 기능이 추가될 때마다 테스트 먼저 시행 후 코드를 작성한다. 테스트 코드를 먼저 작성한 후에 개발을 진행하므로 Test-Driven Development라고 부른다. 소프트웨어를 빠르게 개발할 때 쓰는 방법으로, 변경이나 수정이 잦은(=불확실성이 높은) 애자일 환경에 적합한 방법론이다.

처음 개발해보는 프로그램일 때, 변경이 잦은 프로젝트일 때, 개발한 본인이 아닌 다른 사람이 유지보수를 맡게 될 경우에는 TDD 방식으로 개발을 진행하는 것이 좋다.

TDD 장점

웹개발에서 Unit test 수행 시 실제 데이터가 출력되는 형태로 테스트 코드를 작성해야 하므로 프론트에 JSON 형태 목데이터를 미리 전달할 수 있다. 프론트에서도 백에서도 개발 도중 자료구조를 수정하거나 key 이름을 수정할 필요가 없으므로 커뮤니케이션 비용을 아낄 수 있다. 또한 코드 리팩토링을 할 때 코드를 고치면서 생길 수 있는 오작동을 미리 잡아낼 수 있다.

TDD를 적용한 사례

예를 들어, 생년월일(input)을 입력하면 현재 나이(output)를 출력하는 프로그램을 만든다고 가정하자.

  1. 처음에는 간단히 2015, 2018를 입력하면 3이 출력되게끔 목표를 잡는다.
  2. 2015, 2018를 입력하면 3이 나오는 테스트 코드를 작성한다.
  3. 테스트를 통과할 코드(1번을 목표로 작성한 코드)를 작성한다.
    예) 올해 연도 - 태어난 해 (2018 - 2015)
  4. 테스트 프로그램으로 이 프로그램(3번 코드)을 실행한다.
  5. 통과했으면 새로운 테스트를 추가한다.
  6. 이번에는 살을 붙여서 생월을 추가했을 때 나이를 계산하는 프로그램을 만든다.
  7. 위와 같이 살을 붙이는 작업을 반복해서 수행한다.

예시 출처

Behaviour-Driven Development(BDD)

BDD란

행동 주도 개발. TDD를 기반으로 탄생한 방법론이다. 소프트웨어 개발은 기술적인 숙련도와 비즈니스적 측면에 테스트 할 코드가 없는 상태에서 테스트 코드를 작성하는 것은 어려운 일이다. 기존 TDD 방법론에서는 테스트 코드에 ‘기대값(expected value)‘과 ‘실제 값(actual value)‘을 비교하는 코드를 작성했다면 BDD 하에서는 ‘실제 값’이어야 하는(should be) ‘기대값’과 같은 형태로 스토리를 작성한다.

  1. 특정 값이 주어지고(Given)
  2. 어떤 이벤트가 발생했을 때(When)
  3. 그에 대한 결과를 보장해야 한다(Then)

예)
If I have two apples.
And my friend takes one.
Then I should have one apple.

이것이 BDD 방법론 하에서 코드를 테스트하는 원리다. BDD는 TDD에서 더 나아가 테스트 자체가 요구사양인 개발 방법론이다.

BDD 장점

공식 문서에 따르면 BDD는 TDD에서 뻗어나온 한 갈래다. BDD보다 모든 면에서 나은 방법론이라기보다는 테스트 행위를 다른 관점으로 해석한 게 BDD다. BDD 창시자는 실 개발 코드가 없는 상황에서 테스트 코드부터 작성하는 것은 진입장벽이 높다는 것과 ‘test’라는 단어가 주는 불명확성에 주목했다. 따라서 BDD는 ‘test’를 ‘behaviour’라는 단어로 바꿈으로써 그 장벽을 낮추고 테스트 행위의 의도를 명확히 했다.

Domain-Driven Development(DDD)

DDD란

도메인 주도 설계. 도메인은 사용자가 인식하고 사용하는 모든 것을 가리킨다. 여기서 ‘사용자’는 서비스를 이용하는 유저가 될 수도 있고(이때 도메인은 서비스나 서비스의 기능을 나타낸다) 소프트웨어를 개발하는 개발자가 될 수도 있다. 이 맥락에서 도메인은 개발자가 인식하는 모든 것을 가리키며, 이때 도메인은 코드 한 줄이 될 수도 있다.

DDD는 사용자가 무엇을 필요로 하는지 먼저 생각하고, 사용자가 알 필요가 없는 부분은 사용자에게 공유하지 않음으로써, 의존성을 관리한다. 도메인은 사용자가 필요로 하는 최소한의 요구사항이자, 최대한의 요구사항이다. 모든 연결은 사용자가 필요로 하는 것들과 관련되어 있다.

DDD 주요 개념 요약

  • 도메인: SW로 해결하고자 하는 문제의 영역, 즉 만들고자 하는 서비스를 잘게 쪼개놓은 단위
  • 보편 언어(Ubiquitous language): 프로젝트에 관련된 모든 사람들이 공통으로 써야할 표현 방식. 개발을 집 짓기에 비유하면, ‘욕실’은 집주인, 설계업자, 시공업자 모두에게 욕실이어야 하고, ‘거실’은 모두가 거실로 인식해야 한다.
  • Bounded Context: 프로그램 대상 영역을 덩어리로 나누는 것. 여러 도메인으로 구성된 프로젝트에서 그 도메인을 구분할 수 있게 구분해 놓은 선이다. 같은 모델이라 해도 context에 따라 해석이 달라지기도 한다. 자세한 건 아래에 서술.
  • Model: 도메인의 특정 양상을 묘사한 추상화 시스템으로 도메인 관련 문제를 해결하는 데에 사용한다.
  • Entity: 도메인 모델 설계 시 다른 모델과 구분할 수 있는 모델. 식별자(Id)가 존재한다.
  • Value Object: Entity와 달리 고유 식별자가 없는 모델. 상수나 변하지 않는 값이 여기 해당한다.
  • Aggregate: Entity의 집합으로, 생명주기가 동일한 모델을 모아놓은 root 모델이다.
  • Service: 도메인간 연산을 처리하는 모델
  • Repository: 모델은 저장하는 곳
  • Factory: Entity나 Aggregate를 생성하는 모델

참고) 카카오헤어샵의 도메인 모델 Entity 사용 예시

@Entity
class Reservation {
  
  @Id
  long id;

  @ManyToOne
  ServiceUser serviceUser;

  @ManyToOne
  Shop shop;

  @ManyToOne
  Product product;
}

예시 출처

Bounded Context란

프로그램 대상 영역을 덩어리로 나누는 것을 말한다. 관련한 쉬운 비유가 있다. 출처

주택을 짓는 경우에 빗대어 생각해 볼 때, Bounded Context는 주택 전체를 구성하는 헛간, 농장, 수영장, 메인 주택 등의 큰 요소들 각각을 둘러싼 상황을 의미합니다. 특정 모델은 어떤 bounded context에 놓이는가에 따라 다르게 이해될 수 있습니다.

실제 소프트웨어를 구축함에서의 예를 들면 가령 sales를 담당하는 subdomain이 있을 수 있고, 이를 지원하는 support와 accounting 라는 subdomain 이 존재할 수 있습니다. 이러한 각각의 subdomain이 놓인 환경인 bounded context 내에서 특정 모델 customer 가 보여지는 시각은 매우 상이할 수 있습니다. sales 팀에서 고객을 보는 시각은 주로 사회적 관심사, 좋아하는 것, 욕구 등의 것일 겁니다. 하지만 accounting의 측면에서는 사용자는 그저 하나의 계정으로써 그 사람의 결제정보 만이 중요한 정보일 수 있습니다.

즉 각기 다른 bounded context에서 ubiquitous language는 비록 표현은 같지만 다른 의미를 가지게 됩니다.

DDD 장점

도메인을 정의하고 구성한다는 것은 사용자가 사용하는 영역을 정의하고 설계하는 것을 의미한다. 언뜻 DDD가 개발자에게 제약을 주는 것처럼 인식될 수 있으나, 그렇지만은 않다. 의존성이 높은 프로그램은 하나가 변경됐을 때 수정해야할 게 줄줄이 생기기 때문에 유지보수가 어렵다. 하지만 DDD에서는 도메인으로 개발 영역을 한정하고, 연결 관계(의존성)를 제어한다는 장점이 있다. UX/UI 설계를 통해 사용자가 사용할 수 있는 영역을 제한하고 제한된 영역 안에서 최적화한 경험을 설계할 수 있는 것과 마찬가지다. 사용자는 오히려 제한된 영역 안에서 더 나은 사용자 경혐을 할 수 있다.

또한 도메인(보편 언어)을 통해, 관계자 모두가 인지할 수 있는 범위 안에서 효율적으로 협업이 이루어질 수 있도록 한다. 사용자, 도메인 전문가(보통 PO, PM), 개발자가 명확하게 용어와 개발 범위를 인지함으로써 사용자를 위해 더 많은 것을 생각할 수 있는 길을 제공한다.

참고 문헌