We can work IT out2009/10/31 01:39
이 글은 행위 주도 개발(Behaviour-Driven Developement)를 주창한 댄 놀쓰(Dan North)가 그의 블로그에 쓴 글의 번역입니다. (번역: 이홍주)

행위 주도 개발은 밖에서 안으로 향한 "outside-in" 기법이다. 그것은 비지니스적 요구사항을 식별하는 것부터 시작해서 그런 요구사항 각각을  충족시키는 특성들의 묶음에 대해 파고든다. 각각의 특성들은 "스토리"로 기록되는데,  그것은 인수조건들과 함께 특성들의 범위에 대해 정의한다. 이 글은 스토리들과 그것들의 인수조건(acceptance criteria)을 정의하고 식별하는 BDD 접근법에 대해 소개한다.


서론

소프트웨어 출하는 비지니스적 요구사항을 충족시키는 소프트웨어를 만드는 행위다. 쉬워보이지만, 행적적이거나 환경적 요인들이 이런 사실을 떠올리지 못할만큼 혼란스럽게 만든다. 때때로 소프트웨어 출하는 상급자들을 만족시키는 낙관적인 보고서들을 작성하는 일이거나, 단지 월급 받는 고용인들을 바쁘게 만드는 일을 만드는 것 처럼 보여지기도 하는데, 이에 대한 이야기를 하자는 건 아니다.

보통 비지니스적 요구사항들은 너무 조잡해서 곧바로 소프트웨어를 만드는 데 사용될 수 없기 때문에 (만일 "운영 비용을 5% 절감한다" 라는 요구사항이 주어진다면 어디서부터 코딩을 시작해야 할까?) 일을 완수하기 위해서 중간 단계에서 매개하는 요구사항을 작성할 필요가 있다.

모두가 파악할 수 있을 정도로 요구사항이 명확하다면, 행위 주도 개발(Behaviour Driven Developement)은 요구사항에 대한 인식을구현, 검증되어 출하 가능한 상태의 코드가 되도록 하는 역할을 한다. 그러기 위해서 비지니스 이해관련자들, 분석가, 개발자, 그리고 테스터 모두가 그 일의 범위에 대해 공통적인 이해를 하도록 하는 어떤 수단으로 요구사항을 기술하는 일이 필요하다. 그리고 그것으로부터 모두가 공통적으로 "완료" 라는 말에 동의할 수 있게 되고, "그건 내가 바라던 바가 아니야" 라거나 "내가 이걸 말해준다는 걸 깜빡 했네" 같은 이중의 함정으로부터[각주:1] 벗어나게 된다.

동시에 이것이 스토리의 역할이다. 그것은 요구사항과 비지니스적 이득 그리고 우리 모두가 "완료" 라고 인정할 수 있게 하는 조건들에 대한 설명이어야 한다. 이것은 "요구사항 정의서" 또는 "기능 정의서"[각주:2] 등의 여러가지로 기술되는 다른 애자일 방법론들보다 더 정확한 정의다. (일의 범위가 결정되고 평가되고 합의된 상태라면, BDD 스토리로 비함수적인 요구사항을 손쉽게 기술할 수 있다.)


스토리의 형식

BDD 는 스토리에 형식을 입힌다. 이는 필수적인 건 아니어서 다른 스토리 형식을 쓰면서도 BDD 를 수행할 수는 있다. 하지만 다양한 형태와 크기의 많은 프로젝트들을 통해 효과가 있음이 증명되어왔기 때문에 여기 소개하고 있는 것이다. 스토리는 최소한 아래의 양식에 기술된 모든 요소들을 담고 있어야 한다. 

제목 (한 줄로 된 스토리 설명)
전말:
[역할]로 하여금
[이득]을 얻기 위해서
[기능]이 필요하다.

인수조건: (아래 시나리오들로 표시됨)

시나리오 1: 제목
조건 [조건 설명] 그리고 [또다른 조건 설명]...
만일 [발생한 사건 설명]
그러면 [기대 결과] 그리고 [또다른 기대 결과]...

시나리오 2: ...


스토리 전달하기

하나의 스토리는 몇몇 사람들간의 의사소통의 결과물이어야 한다. 어떤 비지니스 분석가가 비지니스 이해관계자[각주:3]와 기능 또는 요구사항에 대해 이야기하므로써 스토리의 전말(narrative)을 구조화 하는데 도움이 될 수 있다. 그런 후 테스터는 어떤 시나리오들이 중요하고 어떤 게 덜 유용한지 결정하므로써 인수조건의 형태로 스토리에 대한 범위를 정의한다. 기술분야 대표로 하여금 스토리에 포함된 일의 분량에 대한 대체적인 견적 파악을 가능하게 하고 대안을 제시하게 된다. 애초부터 요구사항을 낸 사람들만큼, 시스템에 대한 좋은 아이디어들이 요구사항을 구현하는 사람들로부터 많이 나온다.

이는 일련의 반복적인 과정(iterative process)일 수 있다. 이해관계자들은 그들이 원하는 것에 대해 알지언정 대게 얼마나 많은 노력이 드는지는 모르거나 혹은 어떻게 일이 배분되어야 하는지 모를 것이다. 기술전문가들과 테스트 전문가들의 도움으로 그들은 각각의 시나리오에서 비용과 이득의 타협점(trade-off)을 이해하고 그들이 그것을 원하는지에 대한 결정을 내릴 수 있다. 물론 역시 이는 다른 요구사항들과도 균형을 이뤄야 한다. 즉, 이 스토리를 더 구체화 할 것인지 혹은 다른 스토리로 넘어갈 것인지 말이다.

때때로 개발팀은 대략적인 파악조차 할 수 없을 때가 있다. 이런 경우 그들은 요구사항에 대한 이해를 위해 "spike" 라고 알려진 조사작업을 수행한다. (언젠가 이에 대해 더 자세히 다룰 계획이다.)


적절한 스토리의 특성

Introducing BDD 에서 들었던 것과 같은 예시를 통해서 ATM 에서 현금을 인출하는 경우에 대한 요구사항을 살펴보자.

스토리: 예금자 고객의 현금 인출

(역할) 예금자 고객으로 하여금
(이득) 은행이 문을 닫았을 때 돈을 얻을 수 있게 하기 위해
(기능) ATM 에서 현금을 인출이 필요하다.

시나리오 1: 계좌에 잔고가 있는 경우
(조건) 계좌 잔고가 $100 이다.
그리고 카드가 유효하다.
그리고 출금기에 현금이 충분하다.
(만일) 예금자가 $20 출금을 요청한다.
(그러면) ATM 은 $20 를 출력해야 한다.
그리고 계좌 잔고는 $80 이어야 한다.
그리고 카드가 반환되어야 한다.

시나리오 2: 계좌에 잔고가 부족한 경우
(조건) 계좌에 잔고가 $10 이다.
그리고 카드가 유효하다.
그리고 출금기에 현금이 충분하다.
(만일) 예금자가 $20 출금을 요청한다.
(그러면) ATM 은 현금을 출력하지 말아야 한다.
그리고 ATM 은 잔고가 부족함을 알려야 한다.
그리고 계좌 잔고는 $20 여야 한다.
그리고 카드가 반환되어야 한다.

시나리오 3: 사용 불능인 카드인 경우
(조건) 카드가 사용 불능이다.
(만일) 예금자가 $20 를 요청한다.
(그러면) ATM 은 카드를 반환해야 한다.
그리고 ATM 은 카드가 폐기되지 않고 존속되어왔음을 알려야 한다.

시나리오 4: ATM 에 현금이 불충분한 경우
...

이처럼 계좌 잔고나 카드 상태와 ATM 자체와 관련된 몇가지 시나리오들이 나온다. 이제 위의 스토리가 적절한지 아닌지를 판단하기 위해 파고들어가보자.



제목은 어떤 행위에 대한 것이어야 한다.


스토리의 제목, "예금자 고객의 현금 인출" 은 예금자가 수행하길 원하는 행동을 기술한다. 이 기능을 구현하기 전엔 예금자는 ATM 에서 현금을 출금할 수 없을 것이다. 반대로 그런 기능을 구현하여 적용해주면 출금이 가능해진다. 이는 우리에게 "완료"된 상태가 어떠해야 하는가를 판단하는데 명확한 출발점이 된다. 

만약 제목이 "계좌 관리자" 또는 "ATM 의 동작" 따위었다면 어느 시점이 "완료" 상태인가 불분명해지고 그것과 관련된 것들은 더욱 더 모호해질 꺼다. 일예로, "계좌 관리자"는 대출 계약에 가입시킬지도 모르고, "ATM의 동작"은 현금 카드의 PIN 번호를 바꿔버릴지도 모른다. 그래서 스토리의 제목은 항상 그 시스템을 사용하는 사용자 입장에서 바라본 실질적인 행위로 기술되어야 한다.



전말(narrative)은 역할, 기능, 이득을 포함해야 한다.


"[역할]로 하여금 [이득]을 얻기 위하여 [기능]이 필요하다" 는 템플릿에는 몇가지 장점이 있다. 전말 안에 역할을 구체화 하므로써 기능에 대해 누구와 이야기 해야할지 알게 된다. 이득을 구체화할 때는 스토리 작성자로 하여금 왜 그들이 그 기능을 필요로 하는지에 대해 생각하도록 한다.

그 기능이 실질적인 이득을 가져오지 못한다는 걸 알게 될 경우도 있다. 그런 때 대게는 어떤 스토리를 빠뜨렸음을 의미한다. 현재의 기능에 대한 하나의 스토리가 있을 때, 그 스토리가 전혀 다른 이득을 만들어 내는 상태라면 (그래서 여전히 쓸모 있긴 하지만) 본래의 이득을 위한 전혀 다른 기능에 대한 감춰진 스토리가 필요하다.

위의 예시는 적용될 기능 대해 직접적으로 관련된 예금자가 있기 때문에 그 기능이 어떤 동작을 하는지 조사하는 시작점을 보여준다.


시나리오 제목은 차이점을 나타내야 한다.

스토리를 작성하면서 시나리오들을 나란히 나열할 수 있어야 하고, 그 제목만으로만 각각이 어떻게 다른지가 나타나야 한다. 위 예시에 보면 시나리오의 설명에는 단지 각각의 시나리오가 어떻게 다른지만을 기술하고 있다. "예금자가 잔고가 불충분한 계좌에서 출금하려 할 때 트랜잭션을 처리할 수 없음을 알려야한다" 라는 식으로 장황하게 쓸 필요가 없다. 다른 것들과 비교했을 때 그것의 제목을 통해서 그것에 관심을 기울여야 할지가 명확해진다.


시나리오는 조건, 만일, 그러면[각주:4]의 용어로 기술되어야 한다.

여러 팀들의 경우를 봤을 때 BDD 를 적용하기에 이런 방식은(조건/만일/그러면) 가장 적합하고 유용한 수단이다. 단지 비지니스 사용자들, 분석가들, 테스터들 그리고 개발자들에게 "조건/만일/그러면" 의 어휘들을 적용하므로써 그들은 세상의 모호함에서 벗어나게 되었다.

모든 시나리오들이 단순하지만은 않다. 어떤 것들은 "조건 [기본 조건 내용] 만일 [발생한 사건 상황] 그러면 [기대 결과] 만일 [또다른 사건 상황] 그러면 [새로운 기대 결과] 등등"의 순으로 연속적인 상황들로 표현되는 게 최선이다. 예를 들면 마법사 방식의 웹사이트가 그런데, 복잡한 데이터 모델을 구성하기 위해서 연속적인 화면을 단계적으로 밟게 된다. "조건/만일/그러면" 의 단어들에 익숙해졌다면 사건과 결과를 연속적으로 혼합하는 것이 완벽하게 들어맞는다.

한가지 발생할 수 있는 행태로 의사소통이 필요한만큼 되지 못한 경우가 있다. 그럴 때는 추정된 조건("잔고 이상 출금된상태도 고려해야죠" 라는 말)을 빠뜨렸거나 기대 결과를 ("그런 경우 당연히 예금자는 카드를 돌려받게 됩니다." 라는 식으로) 검증하는 걸 잊었다는 걸 곧바로 알게 될 것이다. 나는 이런 경우를, 개발팀 리더가 분석가들과 개발자들이 서로 동문서답하고 있다고 느꼈지만 그들에게 그렇다는 걸 증명해낼 방법이 없었다고 했던 팀에서 목격한 적이 있다. "조건/만일/그러면" 어휘를 소개한지 며칠만에 그들간의 상호작용이 월등히 좋아졌음을 그들은 확인할 수 있었다.


조건들은 요구된 내용만큼만 빠짐없이 정의되어야 한다.

중도에 추가된 조건들은 혼란을 초래하는데, 그 스토리를 처음 보는 사람에게, 그가 기술진이건 비지니스적 입장에 서있건, 무얼 알고 있어야 하는지를 이해하기 어렵게 한다. 역으로 조건들 중 빠진 게 있다면 그것들은 사실이 아닌 억측이 된다. 주어진 조건으로부터 엉뚱한 결과를 만들게 됐다면 그건 무언가 빠졌기 때문일 거다.

위 예시에서 첫번째 시나리오는 계좌의 잔고, 카드 그리고 ATM 자체에 대한 이야기었다. 그 시나리오를 완성하기 위해 이 모든 것들이 필요하다. 세번째 시나리오의 경우 계좌의 잔고나 ATM 에 현금 보유 여부는 다뤄지지 않았다. 기계가 계좌 잔고나 ATM 의 상태와 상관 없이 카드를 먹은 채로 있을 꺼란 걸 암시한다.


사건(event)[각주:5]은 그것의 특징을 묘사해야 한다.

사건 자체는 매우 간결해야 하며 전형적으로 기술된 시나리오에 오직 한 번 사용 된다. 위에서 언급한 것처럼 어떤 시나리오들은 이보다 더 복잡하기도 하지만, 스토리를 이루는 대부분의 시나리오들은 하나의 사건에 초점을 맞추게 된다. 사건들은 정황(조건들)에 따라 다를 것이고 그에 상응하는 결과가 따르게 된다.


스토리는 한 번의 반복작업(iteration)이 될만큼 작아야 한다.

설명할 수 있는 단위로 쪼개지 않는 한 그렇게 할 수 있는 손쉽고 빠른 방법은 없다. 일반적으로 대여섯개 이상의 시나리오들이 있다면 그 스토리는 서로 비슷한 시나리오들끼리 묶어서 쪼개질 수도 있을 거다.

이글의 ATM 관련 예시로써는 이 스토리를 위해 얼마나 더 많은 시나리오들이 있는지 가늠할 수 없지만 몇 개는 더 나올 수 있을 걸로 짐작한다. 본래 이 스토리에는 세가지 "부품들(moving parts)"이 있는데, 이름하여 계좌 잔고, 현금 카드의 상태 그리고 ATM 의 상태 등이다. 여기서 현금카드에 대해서 좀 더 세분화 될 수 있다. 즉, 카드의 유효기간이 지난 경우 그 카드로 현금을 인출할 수는 없지만 ATM 은 그 카드를 사용자에게 돌려줄 것인가? 만약 ATM 이 트랜잭션을 처리하는 도중에 고장이 난다면? 카드에 당좌 대월 기능이 있는 경우라면?

그래서 아래와 같이 몇몇의 더 작은 단위의 스토리로 쪼개는 것이 좋을 것이다.

  • 예금주가 현금을 인출한다 (가정: ATM 이 정상이고 카드가 유효하다)
  • 예금주가 정지된 카드로 현금을 인출한다 (가정: ATM 이 정상이다)
  • 예금주가 고장난 ATM 으로 현금을 인출한다 (가정: 카드는 유효하다)

이것이 인위적으로 보일 수 있지만, 큰 단위의 스토리의 진행을 비지니스적 용어로 설명해주고 데이터를 근거로한 추적을 가능하게 한다. 여기서 중요한 것은 항상 시나리오들을 통해서 (가정들을 명백히 하면서) 기술적인 흐름보다 (예를 들어, 반복작업에서 데이터베이스 처리나 다음 반복작업에서의 GUI 등의 처리) 비지니스적 흐름을 따라 그 스토리를 풀어내야 한다는 것이다. 이로써 비지니스는 기술적인 용어들을 사용하기보다 그 자체의 용어들을 통해서 그 과정이 설명될 수 있다.


그래서 이것이 Use Cases 와 다른 점은 뭘까?

유즈 케이스란 것에 대해 생각해보자. 나는 앨리스태어 코번(Alistair Cockburn)이 설명하는 (내가 RUP-as-waterfall 프로젝트[각주:6]들에서 맞닥드렸던 Over-engineering 이 발생하는 형태와 대립적인) Use Cases 에 광적인 팬이다. 나는 Use Case 를 바탕으로 한 프로젝트를 수행한 경험이 별로 없기 때문에 그와 비교하는 설명을 할 자신은 없다.

물론 나는 (결과나 목표의) 낮은 정밀도에서 시작해서 높은 정밀도를 향해 일을 진행하면서 그 과정에 더 많은 시나리오들을 받아들이는 그의 프로세스에 동의한다. BDD 관점에서 이것은 비지니스적 결과에서 시작하는 것을 의미하며 고차원적 기능 영역들에 대해 인수조건에 따른 구체적인 스토리들을 파고드는 것이다.

실제로는 어떤 종류의 프로세스가 요구사항을 식별하고 구체화 하는지는 문제되지 않는다. 만일 그것이 생각들을 체계화하는 데 도움이 된다면 요구사항 문서들을 작성하는 것도 괜찮다. 그러나 그 문서들이 모든 생각들을 실질적으로 요약하고 있을 것으로 착각하면서 여기저기 전달해서는 안된다. 그대신 요구사항 문서 또는 Use Case 모음을 한쪽에 놓고서, 머리 속의 모든 해답들을 쏟아낸 지식 만큼, 혹은 최소한 지금 시점에서 업무의 개요를 파악하기 충분할만큼, 비지니스적 결과로부터 스토리들을 정의하는 일에 착수해야 한다.


요약
 
행위 주도 개발은 최소 기능 단위로써, 나아가 출하의 단위로써 스토리를 사용한다. 인수조건들은 스토리의 본질적인 부분이다. 그것들은 스토리의 행위 범위를 정의하는 데 영향을 미치고 또한 스토리가 "완료" 된 상황에 대해 공통적으로 동의할 수 있도록 한다. 뿐만 아니라 계획 단계에서 견적을 추정하는 데 기본 단위로 사용되기도 한다.

가장 중요한 것은 그런 스토리들은 프로젝트의 이해관계자들, 비지니스 분석가들, 테스터들 그리고 개발자들간의 의사소통의 결과물이란 점이다. BDD 는 그것이 개발 프로세스의 산출물인만큼 프로젝트와 관계된 다양한 역할의 사람들 사이에 상호작용에 대한 것이기도 하다.



  1. 역자 주: gumption traps; 어떤 사건 또는 사고방식으로써 프로젝트를 시작하거나 계속 하도록 하는 열의를 잃게 하고 포기하도록 하는 어떤 사건 또는 사고방식을 말한다. [본문으로]
  2. 역자 주: 본래는 promise of conversation, description of a feature 지만 여러가지 개발 방법론에서 말하는 계획,분석 단계 산출물이면 무엇이든 문장의 의미를 해치지 않고 사용될 수 있을 것 같아서 다른 말로 대체함. [본문으로]
  3. 필자 주: 해당 기능에 대해서 실질적인 관심을 보이는 사람이어야 한다. 즉, 스토리에 따라서 운영자, 법무 담당 또는 보안 담당자 등이 된다. [본문으로]
  4. 역자주: 이글은 BDD 방식의 스토리 정의에 대한 것으로 특정 플랫폼의 어떤 도구에 대한 설명은 아니다. 그러나 가장 보편적으로 사용되고 있는 cucumber 에서 "given-when-then" 의 템플릿이 "조건-만일-그러면" 으로 한글화되어 사용되고 있기 때문에 이를 번역에 사용했다. "given-when-then" 은 영어 자연어에서 잘 이해되지만 이를 "조건-만일-그러면" 으로 번역한 후에는 자연어스럽지 않게 되는 문제는 있다. [본문으로]
  5. 역자주: "조건-만일-그러면" 템플릿에 "만일" 에 기술되는 사건을 의미한다. [본문으로]
  6. 역자주: 산출물 중심의 개발 방법론이 적용된 프로젝트로 이해하면 된다. [본문으로]
저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Lyle