반응형

 

TDD(Test Driven Development)란?

 

TDD는 보통 애플리케이션 코드를 작성하기 전에 테스트 코드를 먼저 작성하는 규칙을 지키는 것으로 알려져 있습니다. 이것은 테스트 코드 그 자체와는 상관이 없고 개발 습관에 대한 것입니다. TDD의 교과서인 켄트 벡테스트 주도 개발이라는 책을 보면 TDD의 정수를 제대로 맛볼 수 있을 것이라고 생각합니다.

 

테스트 주도 개발, 인사이트

 

TDD 개발 습관을 가지기 위해서는 다음의 TDD 사이클을 반복하는 습관을 가지면 됩니다.

 

TDD 사이클

 

- 테스트 케이스를 하나 추가한다.
- 모든 테스트를 실행하고 새로 추가한 것이 실패하는지 확인한다.
- 테스트를 통과하기 위한 코드를 작성한다.
- 모든 테스트를 실행하고 전부 성공하는지 확인한다.
- 리팩토링을 통해 중복을 제거한다.

 

테스트 코드 작성 -> 애플리케이션 코드 작성 -> 리팩터링의 순환 반복입니다. 이 순환 반복에서 TDD에서 반드시 지켜야 할 두 가지 법칙이 도출됩니다.

 

1. 어떤 코드건 작성하기 전에 실패하는 자동화된 테스트를 작성하라.
2. 중복을 제거하라.

 

 

 

BDD(Behavior Driven Development)란?

 

애플리케이션 코드를 작성하기 전에 코드가 수행할 행위(요구사항)를 먼저 작성하는 개발 습관입니다.

테스트 코드가 지니는 장점이 많으므로 요구사항을 테스트 코드로 작성합니다. 그러면 BDD는 TDD와 상당한 교집합을 가지게 됩니다.

BDD가 말하는 요구사항은 어떤 행동으로 인해 일어나는 시나리오를 의미합니다. 따라서 주로 유닛 테스트보다는 기능 테스트나 엔드 투 엔드 테스트로 작성합니다. 또한 BDD는 TDD에 비해 요구사항에 중점을 두기 때문에, 요구사항에 대한 이해를 명확히 할 수 있으며 이는 기획자, 테스터 등 비개발자와의 협업 프로세스를 도와줍니다. 비개발자와의 협업을 돕기 위해 테스트 코드를 보편 언어(Ubiquitous language)로 작성하는데 이는 DDD(Domain Driven Design)에서 차용된 개념입니다.

 

 

 

 

 

 

 

 

 

 

 

TDD와 BDD의 공통점

 

이 둘은 개발 습관을 의미합니다. BDD도 TDD의 주기와 법칙을 따릅니다. BDD는 TDD를 기반으로 탄생한 개념이기 때문입니다.

 

우선 코딩해야할 To do list를 작성합니다. 그리고 리스트 중 지금 먼저 할 것을 선택합니다. 코드가 만족해야 할 사항을 테스트 코드로 작성합니다. 실패하는 테스트 케이스가 생겼으니 이제 애플리케이션 코드를 작성합니다. 테스트 케이스가 통과하면 리팩터링을 진행합니다.

 

 

 

TDD와 BDD의 차이점

 

테스트 코드는 어플리케이션 코드를 더 이해하기 쉬운 언어로 설명합니다. 하지만 이 둘은 설명하는 방식이 각자 다릅니다. 설명하는 방식이 다르니 코드 컨벤션도 다릅니다.

TDD는 테스트 코드를 모듈 단위로 작성하므로 개발자가 읽는 코드입니다. 따라서 개발자에게 친화적인 언어로 작성합니다.

BDD는 테스트 코드를 시나리오 단위로 작성하므로 개발자뿐만 아니라 기획자, 테스터와 같은 비개발자도 읽을 수 있습니다. 따라서 누구나 읽을 수 있는 보편 언어로 작성합니다.

 

간단한 계산기 프로그램에서 더하기에 대한 테스트 케이스를 추가하는 경우의 예시를 들겠습니다. 예시 코드는 특정 언어의 문법을 사용한 것은 아니므로 수도 코드로 봐주시기 바랍니다.

 

개발자에게 친화적인 테스트 코드 컨벤션은 다음과 같습니다.

 

describe("Calculator", () => {
  describe("plus", () => {
    it("should return 200, when parameter is 100, 100", () => {
      assert.equal(Calculator.plus(100, 100), 200);
    });
  });
});

 

유닛 테스트를 하나 작성했습니다. Caculator라는 클래스에 정의된 plus라는 메서드에 대한 테스트 케이스 예시입니다. parameter, return과 같이 함수에서의 개발 용어를 직접적으로 사용하는 개발자 친화적인 테스트 네임을 가집니다.

 

보편 언어로 작성된 테스트 코드 컨벤션은 다음과 같습니다.

 

describe("app", () => {
  test("Given empty input, When user input 100 + 100, Then output show 200", () => {
    // Given
    input.hasValue(0);

    // When
    user = new User();
    user.input(100, 100);

    // Then
    expect(output.value).to.eqaul(200);
  });
});

 

앞선 것과 다르게 테스트 네임은 기술적인 개발 용어가 하나도 들어있지 않습니다. 요구사항에 대한 케이스를 하나 기술해놨는데 이것은 비개발자도 충분히 읽을 수 있습니다.

 

코드 컨벤션은 개발자의 취향과 철학에 따라 달라질 수 있으며 절대적인 법칙은 없습니다. 따라서 반드시 위 수도 코드대로 작성해야 하는 것은 아니며 하나의 예시로서 참고만 해주시면 좋겠습니다.

 

 

 

무엇을 사용해야할까?

 

TDD와 BDD는 개발 습관입니다. BDD는 TDD를 기반으로 탄생했으며 이 둘은 같은 개발 습관을 공유합니다. 이 개발 습관을 체화하면 코딩하는 과정에서 탄탄한 설계를 동시에 해내는 경험을 할 수 있습니다.

 

TDD를 사용한다면 유닛 단위의 개발이 정확하고 탄탄하게 진행될 수 있습니다. 그리고 자연스럽게 클린 아키텍처를 지향하게 됩니다.

BDD를 사용한다면 요구사항을 구체적으로 관리하며 개발할 수 있습니다. 주의할 점은 이때 유닛 테스트를 하지 않으면 각 모듈 간의 결합도가 강해질 수 있습니다. 행동 시나리오 하나에는 보통 여러 함수들의 로직이 서로 상호작용하기 때문에, 각각을 따로 분리해 테스트 코드를 작성하지 않으면 그런 위험이 생깁니다.

 

추천해드리는 한 가지 방법은 TDD와 BDD 둘을 상호 보완하도록 사용하는 것입니다. 방법은 BDD 사이클 안에 TDD 사이클을 두는 것입니다. 요구사항이 하나 주어질 때, BDD로 테스트를 작성하고 TDD를 하면서 개발하다가 마지막에 요구사항을 작성한 BDD의 테스트가 통과하는 것을 확인하는 것을 거대한 사이클 하나로 정할 수 있습니다.

 

프론트엔드 진영에서는 UI 혹은 View레이어에서 매우 강한 결합도를 가지는 설계를 하여 모듈의 유닛 테스트가 어려운 경우가 많이 보입니다. 이런 설계를 가질 때에는 UI 혹은 View 레이어에서의 모듈들은 BDD만 하는 것이 유리할 수 있습니다.

 

(이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.)

 

 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기