2020. 2. 2. 16:30

애자일 방법론과 TDD 그리고 BDD

개요


클린 코드나 리팩토링 관련된 서적을 읽으면서 자주 등장하는 개념이고 다른 개발 블로그를 둘러봐도 '애자일'한 작업 환경이라던지 TDD 또는 BDD 등의 용어는 자주 접하게 된다.

그중에서도 최근 가장 떠오르는 것은 단연 TDD인데, TDD에 대해서 알아보기 앞서서 애자일 소프트웨어 개발(Agile software development)은 무엇인지를 먼저 알아야한다. 애자일한 방법론이 무엇일까를 고민하면서 등장한 것이 바로 TDD이기 때문이다. 그 이외에 여러가지의 애자일을 실천할 수 있는 다양한 기법들이 존재한다. 이러한 기법들을 살펴보기 전에 애자일은 무엇일까, 애자일하게 작업한다는 것은 무엇을 의미할까?에 대해서 우선 알아보자.

 

애자일 방법론


애자일 소프트웨어 개발 선언
우리는 소프트웨어를 개발하고, 또 다른 사람의 개발을 도와주면서 소프트웨어 개발의 더 나은 방법들을 찾아가고 있다.
이 작업을 통해 우리는 다음을 가치 있게 여기게 되었다:
공정과 도구보다 개인과 상호작용을
포괄적인 문서보다 작동하는 소프트웨어를
계약 협상보다 고객과의 협력을
계획을 따르기보다 변화에 대응하기를 가치 있게 여긴다.
이 말은, 왼쪽에 있는 것들도 가치가 있지만, 우리는 오른쪽에 있는 것들에 더 높은 가치를 둔다는 것이다.
Kent Beck, Mike Beedle, Arie van Bennekum, Alistair Cockburn, Ward Cunningham, Martin Fowler, James Grenning, Jim Highsmith, Andrew Hunt, Ron Jeffries, Jon Kern, Brian Marick, Robert C. Martin Steve Mellor, Ken Schwaber, Jeff Sutherland, Dave Thomas
© 2001, 상기 저자들
이 선언문은 어떤 형태로든 자유로이 복사할 수 있지만, 본 고지와 함께 전문으로서만 가능하다.

위는 한국어로 번역된 애자일 선언문이다. 애자일 방법론이 목표하는 바를 알 수 있다.

  • 애자일 방법론은 하나의 개발 모델이 아니라 여러 개의 개발 방법론이 있는 개발 방법론 집합체의 원칙에 가깝다.
  • 90년대 중반 기존의 무겁고 규범적인 방법론에서 탈피하여 가벼운 방법론을 지향하며 등장하였다.
  • 애자일 프로그래밍은 기존의 계획과 문서에 의존하는 방식을 부정하고 미래에 대한 예측을 차단하고 지속적인 프로토타입의 완성을 반복하여 그때그때 요구사항을 추가하고 문제점을 해결하여 점차적으로 큰 규모의 소프트웨어를 완성하는 개발 방식이다.

 

요약하자면 애자일은 컴퓨팅 환경과 시대가 변화함에 따라서 기존에 폭포수 모형 개발론(Waterfall Model)방식으로는 한계점이 존재했고 그 한계점을 극복하기 위해서 개발과 함께 즉시 피드백을 받아 유동적으로 개발하는 방법론을 이야기한다.

쉽게 한마디로 표현하자면 '유연하게 일하는 방식'정도로 표현할 수 있겠다. 기획, UI/UX 디자인, 개발, 수정의 순서대로 일이 진행되고 다시 되돌아 갈 수 없도록 일을 하는 방식을 바로 폭포수 개발 방식이라고 부르고 기존에는 이런 단계적으로 프로젝트가 진행되었다. 클라이언트의 요구사항이 유동적으로 계속 변하지가 않고 마지막 프로젝트의 완성본이 너무나도 명확하다면 폭포수 개발 방식은 너무나도 효율적이겠지만 현실은 그렇지 않다.

특히 현대에 와서 각종 요구와 개발하는 방식이 많아진 지금은 더더욱 폭포수 개발 방식으로는 명확한 한계점이 보이기 시작한 것이다. 그래서 하나의 프로토타입 단위로 쪼개서 테스트 코드를 작성하고 클라이언트들의 즉각적인 피드백을 받아서 수정하고 실수와 오차를 줄이며 진행해나가는 방식인 애자일 방식이 최근에 들어서 각광받고 널리 알려지기 시작한다.

애자일 자체로는 어떤 개발 모델이 아니라 방법론의 집합체, 규약과도 같은 것이라고 앞서 말했다. 그래서 단순히 이 애자일을 제한적으로 프로그래머에게만 해당하는 내용이라고 생각한다면 애자일의 근본 개념과도 위배된다. 따라서 모든 직무에서 애자일하게 일하는 방법들을 적용할 수 있다.

구체적으로 애자일 방법론에는 칸반과 TDD와 BDD, 분산 애자일, 페어 프로그래밍, 스크럼 등 다양한 방법들이 존재한다.

여기서 우리는 가장 익숙하고 빈번하게 들리는 칸반과 TDD, BDD에 대해서 알아보도록 하자.

 

칸반(Kanban)


칸반 보드의 형식

어쩌면 앞으로 이야기하게 될 TDD나 BDD보다 훨씬 시각적이고 트렐로나 노션과 같은 협업툴에서 제공하는 칸반보드 기능에 익숙한 사람은 위의 사진만 보고도 단번에 이해가 갈 정도로 우리에게 익숙한 방법일 것이다.

칸반은 연속적 흐름 처리 방식이다. 칸반 보드로 시각화하고 각각 단계마다 열로 표시된다. 이때 이 열은 우선순위가 높다면 위에 낮다면 아래에 배치하게 된다. 이들 이슈는 수영 레인(Swimlane)이라고 불리는 행으로 진행 상황을 알 수 있다.

칸반에서의 핵심은 진행 중인 작업(WIP, Work-In-Process)이 동시에 개발이 진행 될 수 있는 아이템의 수를 제한하는 것이다. 관리자는 이 WIP에 여유가 있을 때만 작업을 왼쪽에서 오른쪽으로 당길 수 있다. 칸반은 이렇게 동시에 처리할 수 있는 이슈의 수를 제한함으로써 생산성을 제어한다.

위의 사진을 예로 들면 Doing에 WIP제한을 3개로 둔다면 Doing에서 Done으로 옮기지 않는 이상 To Do에 있는 내용을 Doing으로 옮길 수 없다.(이미 WIP의 제한이 3개로 가득차 있기 때문이다.)

장점

  • 흐름을 시각화 할 수 있다.
  • 일일 스탠드업, 데모, 레트로스펙티브와 같은 오버헤드 활동에 시간을 덜 소비할 수 있게 해준다.

 

단점

  • 애자일을 새로 접하는 팀에는 어려울 수 있다.(다른 방법론과 달리 프로세스가 명확하게 정의되어 있지 않기 때문)
  • 좋지 않은 프로세스에 무기한으로 빠지기 쉽다.

 

TDD(Test-driven development)


Test the program before you write it. - kent beck

kent beck(익스트림 프로그래밍의 창시자)은 2003년에 TDD가 단순한 설계를 장려하고 자신감을 불어넣어준다고 말했다.

TDD는 Test Driven Development의 약어로 말그대로 테스트 주도 개발을 의미한다. 테스트로 이끌어가는 개발 환경, 작업을 표현할 때 주로 사용되는 표현이며, 쉽게 말해 구현코드를 작성하기 전에 테스트 부터 작성한다는 말이다.

쉽게 말하면 선 테스트 코드 작성, 후 구현을 말한다.

소프트웨어 개발 프로세스 중에서의 TDD

  1. 먼저 요구사항을 검증하는 테스트 케이스를 작성한다
  2. 그 테스트 케이스를 통과하기 위한 최소한의 코드를 생성한다.
  3. 마지막으로 작성한 코드를 표준에 맞게 리팩토링한다.

테스트 코드를 작성한다는 것이 무엇을 어떻게 만들어야하는지 감이 잘 안올 수 있는데, 그 이전에 가장 먼저 염두해두어야 할 것은 내가 지금 만들려고 하는 코드가 어떠한 결과를 만들어낼 것인지를 인지하고, 그 결과가 올바르다면 어떻게 될 것이다라는 것을 코드로 구현하고 컴파일이 제대로 돌아간다는 것을 확인을 하는 과정이다.

장점

  • 코드의 확장성 및 유지보수 용이해진다.(코드의 모듈화가 자연스럽게 이루어짐)
  • 프로그램 소스코드 기록(테스트 코드로 인해서 코드의 목적성과 과정을 기록하는 효과)
  • 총소유비용(TCO) 절감할 수 있다.

 

단점

  • 숙련되기까지 다소 시간이 소요된다.
  • 선행 투자가 많이 필요하다.

 

BDD(Behavior-driven development)


BDD는 Behavior-drive develpment의 약자로 행위 주도 개발이라고 해석할 수 있다. 기본적으로 TDD에 기반을 두고 있으며 겉보기에는 큰 차이가 나지 않는 것처럼 보일 수도 있다. BDD는 TDD에서 한발 더 나아가 테스트 케이스 자체가 요구사양이 되도록 하는 개발 방식이다.

Dan north는 TDD를 코칭 하던 시절 'Test'라는 단어를 쓰지 않는 편이 오히려 TDD의 원리를 이해하는데 더 쉽다고 생각했고, test보다는 행위에 집중했다. 그는 테스트 메소드의 이름을 "어떤 것을 해야만하는지(should do something)"이라는 문장으로 작성하여 행위에 대한 테스트에 집중할 수 있다.

TDD는 테스트를 작성하고 그 테스트를 통과시키는 코드를 작성하는 흐름을 기본으로 가져간다고 앞서 설명했다. 게다가 테스트 단위로 함수 단위로 매우 작아서 작성하는 거의 모든 함수가 테스트 대상에 포함되기 때문에 현업에서 사용하기에는 다소 번거로움이 느껴질 수도 있다.

그래서 TDD에서 파생되어 등장한 BDD는 함수 단위의 테스트를 권장하지 않고 시나리오 기반의 테스트 케이스를 작성한다. 이때 이 시나리오는 개발자가 아닌 사람이 봐도 이해할 수 있을 정도여야 한다. 하나의 시나리오는 Given, When, Then구조를 가지는 것을 기본 패턴으로 권장한다.

  • Feature : 테스트에 대상의 기능/책임을 명시한다.
  • Scenario : 테스트 목적에 대한 상황을 설명한다.
  • Given : 시나리오 진행에 필요한 값을 설정한다.
  • When : 시나리오를 진행하는데 필요한 조건을 명시한다.
  • Then : 시나리오를 완료했을 때 보장해야 하는 결과를 명시한다.

이런 패턴을 가지고 BDD는 프로젝트내에서 서로 다른 업무를 가지고 있는 구성원들 간의 커뮤니케이션의 용도로 발전했다.

어찌보면 프로그래머들에 좀더 가까운 TDD보다 전 구성원이 이해와 합의를 함께 이루어낼 수 있다는 점에서 더욱 '애자일'스러운 기법은 이 BDD가 아닐까 싶다.

장점

  • 비즈니스에서 요구하는 가치를 제공한다.
  • 다른 커뮤니티 구성원들도 참여할 수 있다.

 

단점

  • BDD를 지원하는 소프트웨어 툴은 비교적 적다.

 

TDD와 BDD의 차이


주의해야할 것이 테스트 프레임워크(OOOunit 시리즈)를 사용한다고 전부 TDD는 아니라는 점이다. 오히려 테스트 프레임워크를 사용해서 자신의 코드를 완성 후에 테스트 코드를 짜고 이를 돌렸다면 이것은 TDD보다는 BDD에 가깝다. 코드의 완성 과정에서 테스트가 영향을 주지 않았다면 이는 테스트 케이스 자체가 요구사양이 되기 때문이다.

TDD는 개발코드의 완성이 목적이고 BDD는 개발 결과의 검증이 목적이다.

조그마한 개발팀에 있고 일하는 대상이 모두 개발자라면 굳이 BDD를 사용할 필요가 없다. 왜냐하면 BDD는 TDD 사용자들의 공식화된 좋은 습관들 위에 형성되었기 때문이다. 하지만 BDD는 개발자의 언어로 이루어지는 TDD에 반해 테스트 시나리오를 읽는 대상이 좀 더 넓혀진 개념이다.

쉽게 요약하자면 TDD는 코드 자체에 집중한 테스트 코드를 작성하고 BDD는 시나리오를 패턴화해서 여러 구성원들이 테스트 코드를 검증할 수 있도록해서 더욱 비즈니스 요구 사항을 빠르게 반영할 수 있게 된다.