! This post is also available in the following language. 영어

사용자 스토리 포인트로 스마트하게 프로젝트 진행하기(feat. LINE Pay 개발 팀)

시작하면서

이번 글에서는 LINE Pay에서 앱 개발과 서버 개발을 진행하면서 스토리 포인트를 적용하고 활용한 사례를 공유합니다. 이 사례를 통해서 글을 읽는 여러분도 스토리 포인트를 제대로 이해하고 활용할 수 있는 기회를 얻으시길 바랍니다.

 

스토리 포인트?

스토리 포인트를 설명하기 전에 스토리 포인트와 관련된 세 가지 개념을 먼저 알아보겠습니다.

  • 사용자 스토리(user story): 사용자 스토리는 통상 ‘요구 사항’이라고 부르는 시스템의 기능 설명을 사용자 관점에서 이야기하는 것입니다. 이때 모든 요구 사항을 사용자 스토리로 간주해서는 안 되고 사용자에게 가치 있는 것들만 사용자 스토리 대상으로 간주해야 합니다. 예로 가입 기능을 만들어야 한다고 가정해 봅시다. 보통이라면 ‘사용자들이 LINE Pay를 사용할 수 있도록 가입 기능을 제공해야 한다.’라고 기능을 설명할 것입니다. 이를 사용자 관점으로 변경하여 ‘LINE Pay 비사용자는 LINE Pay에서 제공해 주는 각종 기능을 사용하기 위하여 약관에 동의한 후 가입 버튼을 눌러 LINE Pay 회원이 될 것이다.’라고 작성한 것이 사용자 스토리입니다. 보통 마치 표준처럼 ‘~는 ~하기 위하여 ~할 것이다.'(영어로는 ‘As ~, in order to ~, I will’) 형식을 사용하지만, 꼭 이 형식을 따를 필요는 없습니다. 사용자 스토리에서 가장 중요한 것은 사용자 관점에서 사고를 한다는 것입니다.
  • 스프린트(sprint): 스프린트는 특정 기간을 정해서 그 기간 단위로 움직이는 것을 말합니다. 예로 2주 단위로 스프린트를 운영한다고 할 경우, 2주 간격으로 해당 기간 동안 수행할 일들을 계획하고, 수행한 일들을 회고하는 것을 반복하는 것입니다.
  • 벨로시티(velocity): 벨로시티는 스프린트당 얼마나 많은 스토리 포인트를 획득할 수 있는지를 나타내는 값입니다. 여기서 스토리 포인트를 획득한다는 것은 사용자 스토리를 실제 동작하는 기능으로 구현해 전달한 경우를 말합니다.

 

개념

스토리 포인트(story point)는 사용자 스토리를 실제 동작하는 기능으로 구현(실현이라고 쓸 수도 있지만 여기서는 구현으로 하겠습니다)하는 게 얼마나 어려운지를 나타내는 값입니다. 이 값은 어떤 한 개인에게 의존하지 않는, 스토리 포인트를 사용하는 해당 집단의 다수의 관점에서 객관적인 값입니다. 우리에게 매우 익숙한 MD(man-day)라는 개념과 비교해 봅시다. MD는 공수를 나타내는 단위 중 하나로 한 사람이 특정 기능을 구현하기 위해 얼마나 많은 시간이 필요한지를 나타내는 값입니다. 예를 들어 가입이라는 기능을 브라운이라는 사람이 구현할 때 하루가 걸린다면 이를 1MD라고 표현합니다. MD는 사람(브라운)과 시간이라는 두 개의 척도로 노력(공수)을 표현하는 방식입니다.

스토리 포인트는 MD와 다르게 사람과 시간이라는 척도를 배제합니다. 구현하려는 사용자 스토리 그 자체에만 온전히 집중합니다. 어떤 사용자 스토리를 구현하는 게 얼마나 어려운지를 나타내기 위해서는 기준이 필요하며, 그 기준과 비교한 상대적인 어려움을 표현한 값이 바로 스토리 포인트입니다. 예를 들어 가입하기와 로그인 그리고 로그아웃 사용자 스토리가 있다고 가정하겠습니다. 세 개의 사용자 스토리 중에서 가장 구현하기 쉬운 사용자 스토리는 로그아웃 사용자 스토리일 것입니다. 가장 구현하기 쉬운 로그아웃 사용자 스토리를 기준으로 삼고, 이 기준과 비교해 가입하기 사용자 스토리와 로그인 사용자 스토리를 구현하는 것의 상대적인 어려움을 추정하는 것입니다.

더 쉽게 설명하기 위해 거리 개념을 도입해 보겠습니다. 서울과 부산까지의 직선거리는 약 325.5km입니다. 이 거리가 매우 길다는 것을 쉽게 인지하실 겁니다. 그 이유는 ‘1km’라는 기준이 얼마나 되는지 우리 모두 이미 알고 있기 때문입니다. 1km를 가는 데 얼마나 소요되는지 인식하고 있기 때문에 325.5km가 매우 멀다는 것을 쉽게 인지할 수 있습니다. 이처럼 스토리 포인트도 거리에서의 1km와 같은 기준을 잡은 뒤 그 기준과 비교해 스토리 포인트를 결정해서 각 사용자 스토리 구현의 어려움을 측정합니다. 거리 개념과 함께 MD와 좀 더 비교를 해보겠습니다. 서울에서 부산까지 이동하는 데 걸리는 시간은 이동 수단에 따라 다릅니다. 자동차로는 약 5시간, 기차로는 약 2시간 40분, 비행기로는 약 1시간 걸립니다. 이동 수단에 따라 걸리는 시간은 다르지만 서울에서 부산까지의 직선거리는 여전히 325.5km입니다. 여기서 MD와 스토리 포인트의 차이점을 명확히 파악할 수 있습니다. 이동 수단 별로 걸리는 시간을 MD라고 볼 수 있고, 이동 수단에 관계없이 변하지 않는 값인 325.5km라는 거리가 스토리 포인트라고 볼 수 있습니다. 즉, 사용자 스토리를 구현하는 데 걸리는 시간은 각 개발자에 따라 다르겠지만, 사용자 스토리 그 자체에 의존적인 스토리 포인트는 변하지 않습니다.

 

이점

스토리 포인트를 활용했을 때 얻을 수 있는 이점은 팀의 현재 움직임과 팀과 관련된 향후 일정을 쉽고 빠르게 파악하고 예측하며 계획할 수 있다는 점입니다. 또한 외부 환경 요소에 덜 의존하기 때문에 보다 객관적인 값을 지속적으로 이용할 수 있습니다. 좀 더 쉽게 설명하자면, 스토리 포인트를 이용해서 예측하고 계획하면 스프린트 기간에 발생할 수 있는 너무 많은 회의나 갑자기 발생한 장애, 병가 등의 모든 예외 상황을 전부 수용할 수 있다는 것입니다.

기존 MD 방식은 사람과 시간이라는 척도를 이용한다고 말씀드렸습니다. 브라운이 가입 사용자 스토리를 구현하기 위해 1MD가 필요하다고 추정했을 때, 코니는 기존 시스템을 잘 모르고 구현 언어도 익숙하지 않기 때문에 3MD가 필요할 수도 있습니다. 이처럼 MD는 같은 사용자 스토리라도 사람에 따라 다른 값이 도출됩니다. 프로젝트에 참여하는 사람에 따라 다른 값이 도출되기 때문에 프로젝트의 규모를 객관적인 값으로 도출하기 어렵고, 개개인에 따라 달리 스케줄링되기 때문에 예측 및 계획이 불안정합니다. 하지만 스토리 포인트에선 사용자 스토리를 구현하는 담당자가 누구든 상관없이 무조건 동일한 값으로 관리됩니다. 가입 사용자 스토리가 3 스토리 포인트라고 가정한다면, 브라운이 구현하든 코니가 구현하든 가입 사용자 스토리는 3 스토리 포인트입니다. 이런 특성 때문에 사용자 스토리와 스토리 포인트에 기반해 계획을 전략적으로 수립할 수 있습니다.

 

스토리 포인트 활용

스토리 포인트의 대략적인 개념을 알았으니 이제 활용하는 방법을 알아보겠습니다.

 

기준 사용자 스토리 정하기

위에서 말씀드렸듯이 스토리 포인트는 어떤 기준을 두고 이 기준과 비교해 상대적으로 추정하는 값입니다. 따라서 거리 개념에서의 1km처럼 기준이 되는 사용자 스토리를 정해야 합니다(기준이 되는 사용자 스토리를 ‘골든 스토리’라고도 부릅니다). 그런데 기준을 정하기 전에 먼저 스토리 포인트의 범위를 정하는 것이 좋습니다. 간단하게 1에서 5 사이의 수를 손가락을 이용해 표현하는 방법이나 XS, S, M, L, XL 등으로 나뉘는 티셔츠 사이즈 등을 이용할 수도 있고, 피보나치수열을 응용한 0, 1, 2, 3, 5, 8, … 과 같은 수열을 이용하기도 합니다. 각 팀의 특성에 맞게 선정해서 사용하는 것을 추천합니다. 이 글에서는 LINE Pay 팀에서 사용하는 피보나치수열을 이용해 설명하겠습니다.

피보나치 같은 수열을 이용할 경우 최댓값을 설정해 놓는 것이 좋습니다. 이번 글에선 최댓값을 13으로 설정하겠습니다. 그러면 스토리 포인트로 사용할 수 있는 값은 0, 1, 2, 3, 5, 8, 13이 됩니다. 스토리 포인트의 범위가 정해지면 어느 값을 기준으로 삼을 것인지 정합니다. 3과 같은 중간 값을 기준 값으로 사용할 수도 있고, 획득 스토리 포인트를 증가시킬 수 있는 가장 작은 값인 1을 사용할 수도 있습니다. 참고로 0은 사용자에게는 가치가 있지만 매우 사소한 노력으로 제공할 수 있는 사용자 스토리에 사용할 수 있는 값입니다. 1을 기준 값으로 사용한다고 가정해 보겠습니다. 위에서 예시로 사용한 사용자 스토리로 가입하기와 로그인, 로그아웃이 있었습니다. 이 중에서 어려움의 크기가 가장 작다고 생각하는 사용자 스토리가 로그아웃이라고 한다면, 이 로그아웃이 기준 사용자 스토리가 됩니다. 나머지 가입하기와 로그인의 스토리 포인트는 이 로그아웃을 기반으로 추정합니다. 또한 로그아웃 사용자 스토리를 최솟값으로 잡았을 땐 로그아웃 사용자 스토리보다 더 쉬운 작업은 없어야 하며, 있더라도 0 스토리 포인트로 할당할 만큼 어려움의 크기가 아주 작은 작업이어야 합니다.

 

스토리 포인트 추정

스토리 포인트를 사용할 때 가장 중요한 부분입니다. 추정이라는 단어에서 알 수 있듯이 스토리 포인트는 정밀한 값을 요구하는 것이 아닙니다. 대부분 이 추정 작업을 진행할 때 정밀한 값을 찾으려고 노력하는데요. 그렇게 하면 스토리 포인트를 잘못 사용하는 것입니다. 스토리 포인트는 물론, 더 나아가 애자일(agile)의 목적에 부합하지 않습니다. 여기서 의문점이 하나 생길 수 있습니다. ‘아무리 정밀한 값을 추정하는 게 아니라고 하지만 너무 어림잡아 하는 것 아닌가?’라는 의문점입니다. 하지만 걱정할 필요 없습니다. 이렇게 추정하는 값은 지속적인 반복을 통해 결국 정밀한 값으로 근접해 갑니다.

참고. 정밀한 값으로 근접해 가는 이유는 큰 수의 법칙(대수의 법칙, the Law of Large Numbers) 때문입니다. 큰 수의 법칙이 잘 생각나지 않거나, 잘 몰라서 빠르게 이해하고 싶으신 분이라면 ‘노바 – 예측 과학의 현주소(참고)’의 큰 수의 법칙 부분을 보시면 아주 쉽게 공감할 수 있을 겁니다.

대부분 추정하는 작업이 어려워서 처음에는 시간을 대입해 스토리 포인트를 추정하고 사용하는 방식을 채택합니다. 이를테면 4시간짜리 업무를 1 스토리 포인트라고 설정해 사용하는 것입니다. 그런 방식으로 스토리 포인트를 사용해 보고 나선 기존에 추정하던 방법과 별 다를 게 없다고 생각하며 스토리 포인트를 더 이상 활용하지 않습니다. 이는 매우 잘못된 방법입니다. 이런 경험 때문에 사용하지 않고 있었다면 이 글을 통해 인식을 바꿔보는 게 좋겠습니다.

스토리 포인트 추정 작업은 별도로 추정 시간을 두어 진행할 수도 있고 스프린트가 시작하는 플래닝 단계에서 진행할 수도 있습니다. 스토리 포인트를 추정할 때 자주 사용하는 기법 중 하나로 ‘플래닝 포커(planning poker)’가 있습니다. 간단히 설명하자면, 사용자 스토리를 설명한 후에 각자 해당 사용자 스토리에 어느 정도 포인트를 할당할지 생각한 뒤 해당 값이 적혀 있는 카드를 선택하거나 종이에 그 값을 적은 후 동시에 공개해 가장 많이 나온 값으로 스토리 포인트를 할당하는 기법입니다. 의견이 갈릴 경우 각자의 의견을 듣고 다시 포커를 진행해 스토리 포인트를 추정하는 작업을 반복합니다(더 자세한 설명은 이곳을 참고하시기 바랍니다).

추정 작업은 가벼운 분위기에서 빠르게 진행해야 합니다. ‘B라는 기능이 A라는 기준 스토리 포인트와 비교해 몇 배나 어려울 것인가’라는 사고와 함께 감각적으로 빠르게 진행해야 합니다. 예를 들어 로그인 사용자 스토리가 로그아웃 사용자 스토리보다 2배 어렵다고 생각한다면 로그인 사용자 스토리의 스토리 포인트는 2가 됩니다. 아래와 같이 가입하기 사용자 스토리로 예를 더 만들어 봅시다.

  • 브라운: 난 로그아웃 사용자 스토리의 3배 정도가 적당하다고 봐.
  • 코니: 난 로그아웃 사용자 스토리보다 5배는 어렵다고 봐. 이것저것 신경 쓸 게 많다고.
  • 레너드: 나도 로그아웃 사용자 스토리의 3배보다는 더 어렵다고 생각하는데 5배까진 아닌 것 같다는 생각이 들어.

위와 같은 상황이라면 가입하기 사용자 스토리의 스토리 포인트는 5가 됩니다. 스토리 포인트를 추정하는 작업은 정밀한 값을 요구하는 것이 아니며, 레너드와 같이 불확실한 의견이 있다면 이를 내포하여 3보다는 5를 선택하는 것이 더 좋은 방법입니다.

 

활용하기

여기까지 설명하면서 가장 중요한 점을 제가 빠뜨린 것 같습니다. 스토리 포인트는 같은 일을 수행하는 팀 내에서 통용되는 단위입니다. 예를 들어 A 팀과 B 팀이 있는데 A 팀은 스프린트당 20 스토리 포인트를 획득하고 B 팀은 스프린트당 30 스토리 포인트를 획득한다고 가정해 봅시다. 이 경우 B 팀이 A 팀보다 우월하다고 할 수 있을까요? 정답은 ‘스토리 포인트를 그러한 비교 잣대로 사용해서는 안 된다’입니다. A 팀과 B 팀은 각자 사용자 스토리 포인트의 기준 단위가 다르기 때문에 비교할 수가 없습니다. 예로 A 국가에서 기본 거리 단위로 km를 사용하고 B 국가에서 기본 거리 단위로 마일(mile)을 사용하고 있을 때 A 국가에서의 거리 단위 1과 B 국가에서의 거리 단위 1을 비교하려는 것과 동일한 행위입니다.

여기까지 준비됐다면 이제 ROI(return on investment) 사분면 분석이나 카노(Kano) 모델을 응용한 우선순위 선정 작업을 통해 전략적으로 계획을 수립할 수 있습니다. 두 전략 모두 스토리 포인트와 사용자에게 주는 가치의 정도에 따라 어느 것을 먼저 할 것인지 혹은 어느 것을 하지 않을 것인지 선택하는 데 도움을 줍니다.

ROI 사분면 분석을 응용한 예시
카노 모델을 응용한 우선 순위 산정 예시

이제 스토리 포인트를 어떻게 활용할 수 있는지 예시와 함께 확인해 봅시다. 보통 예측과 계획에서 자주 활용합니다. 팀원이 총 5명인 팀에서 2주 단위 스프린트로 스토리 포인트를 처음 활용하는 상황을 가정해 보겠습니다. 구현해야 할 사용자 스토리들의 스토리 포인트 추정은 모두 완료한 상황입니다. 처음 적용해 보는 것이니 한 번의 스프린트에서 한 명이 획득할 수 있는 스토리 포인트가 3 스토리 포인트라고 단순하게 가정하면 이 팀이 스프린트에서 획득할 수 있는 총 스토리 포인트는 15 스토리 포인트가 됩니다. 이제 백로그에서 사용자 스토리를 꺼내 15 스토리 포인트를 채웁니다. 5 스토리 포인트인 가입하기, 3 스토리 포인트인 로그인, 1 스토리 포인트인 로그아웃, … 이렇게 15 스토리 포인트를 채운 후 거기에 맞춰 스프린트를 계획하고 시작합니다. 

2주 후 스프린트를 종료하면서 해당 팀이 획득한 스토리 포인트를 확인합니다. 만약 10 스토리 포인트를 획득했다면 다음 스프린트는 15 스토리 포인트와 10 스토리 포인트의 중간인 13 스토리 포인트로 계획하여 진행해 봅니다. 2주 후 스프린트를 종료하면서 획득한 스토리 포인트를 또 확인합니다. 참고로 스프린트를 종료할 때 어떤 사용자 스토리의 절반 정도를 수행했다고 해서 해당 스토리 포인트의 절반을 획득하는 것은 아닙니다. 스토리 포인트는 해당 스프린트에서 사용자 스토리를 완전히 구현해 전달했을 때에만 획득합니다. 이렇게 3번 정도 반복하면 팀이 스프린트당 획득할 수 있는 최대 스토리 포인트가 몇인지 대략 파악됩니다. 이게 벨로시티입니다. 어떤 팀이 스프린트당 13 스토리 포인트를 획득할 수 있다고 평가했다면 이제 팀의 벨로시티는 13 스토리 포인트이고, 이를 기반으로 계획 및 예측하고 회고를 진행합니다. 예측할 땐 다음과 같이 활용합니다. 특정 에픽(epic, 사용자 스토리들의 묶음)의 스토리 포인트가 60 스토리 포인트이고 팀의 벨로시티가 13 스토리 포인트라고 한다면, 이 팀이 해당 에픽을 완료하려면 약 10주가 필요하다고 예측합니다. 너무 간단합니다. 

회고에선 스프린트를 종료할 때 획득한 스토리 포인트와 팀 벨로시티를 기반으로 해당 스프린트를 평가합니다. 팀 벨로시티보다 더 많은 스토리 포인트를 획득했다면 ‘왜 그렇게 됐는지? 팀 벨로시티를 높일 필요는 없는지?’를 이야기해보고, 더 적은 스토리 포인트를 획득한 경우 역시 ‘왜 그렇게 됐는지? 팀 벨로시티를 낮출 필요는 없는지?’를 이야기해 봅니다. 그러면서 팀 내에 존재하는 장애물을 제거하는 액션 아이템을 도출하여 진행하고, 잘했던 부분들은 공유해서 벨로시티를 조금씩 높여가며 더욱 기민한 팀을 만들어 갑니다.

중요한 얘기를 하나 더 하겠습니다. 스프린트를 계획하면서 확정했던 스토리 포인트를 다 획득하지 못해도 자책할 필요 없습니다. 위에서 말한 것처럼 업무를 수행하다 보면 갑자기 회의가 많아지거나 장애 상황이 발생하는 등 여러 가지 예상치 못한 일들이 발생할 수 있습니다. 그런 상황들이 다 반영된 것이 팀 벨로시티입니다. 회고를 하면서 예상치 못한 몇몇 상황 때문에 이번 스프린트에서는 스토리 포인트를 획득하지 못했지만, 다음 스프린트에서는 그런 상황이 발생하지 않을 것이라고 예측한다면 팀 벨로시티 보다 더 높은 스토리 포인트를 계획할 수 있습니다. 스프린트에서 계획한 스토리 포인트를 모두 획득하거나 획득하지 못한 것으로 스프린트의 성공 혹은 실패를 평가하는 것이 아닙니다. 스토리 포인트 획득 여부는 해당 스프린트가 어떤 상황에 있었는지를 나타내는 상태 값이라고 보는 것이 더 정확합니다. 만약 벨로시티가 조금씩 지속적으로 내려간다면 어떤 외부 요인이 있는 것인지 면밀히 검사해 보고 이를 해소하는 것이 좋습니다.

 

LINE Pay에서 스토리 포인트 활용 사례

이제 LINE Pay에서 스토리 포인트를 활용한 사례를 공유하겠습니다. 솔직히 위에서 여러 중요한 개념을 너무 많이 요약하면서 오해가 생길 수 있는 부분이나 본질을 이해하지 못하고 잘못 사용하면 오해가 생길 수 있는 부분들이 다소 있었는데요. 저희 사례를 소개하면서 보충할 생각입니다. 저는 LINE Pay 서버 개발을 하다가 LINE Pay 앱 개발 팀을 구축해 거의 3년 정도 앱 개발 팀에 있었고, 지금은 다시 서버 개발 팀에서 업무를 수행하고 있습니다. 각 팀에 속해 스토리 포인트를 활용한 사례들을 비교하면서 말씀드리겠습니다.

 

사용자 스토리 작성

먼저 LINE Pay에서 어떤 방식으로 사용자 스토리를 작성했는지 말씀드리겠습니다.

 

사용자 정의

LINE Pay에는 LINE 앱을 이용해 결제를 수행하는 일반 사용자와 LINE Pay를 통해 서비스를 제공하는 가맹점 사용자가 있습니다. 그렇다면 LINE Pay 팀에서 고려하는 사용자는 이러한 일반 사용자와 가맹점 사용자일까요? 아닙니다. 여기서 사용자는 상기한 최종 사용자만을 의미하지 않으며, 각 팀마다 다릅니다. 앱 개발 팀에 있을 때는 LINE Pay 앱이나 가맹점 앱에 따라 사용자 스토리가 대부분 일반 사용자 또는 가맹점 사용자로 도출됐습니다. 하지만 서버 개발 팀에서는 달랐습니다. 몇 가지 사용자 스토리는 앱 개발 팀에서와 같이 일반 사용자나 가맹점 사용자 대상으로 도출됐지만, 대부분은 앱 개발자나 사업 팀 멤버 등 다른 유형의 사용자 대상으로 사용자 스토리가 도출됐습니다. 이처럼 사용자 스토리의 사용자는 최종 사용자만을 의미하지 않습니다. 해당 팀에 접해 있고 해당 팀에서 창출하는 가치를 최종적으로 이용하는 대상이 사용자입니다. 예를 들자면 앱 개발 팀이 API를 사용할 수 있도록 서버 개발 팀이 API를 만들고 제공하는 사용자 스토리를 작성했을 경우엔 앱 개발 팀이 사용자입니다.

 

사용자 스토리 형식

사용자 스토리를 작성할 때 형식에 너무 얽매이지 않도록 관리했습니다. ‘As ~, in order to ~, I will ~’이나 ‘In order to ~, as a ~, I want ~’와 같은 형식에 너무 얽매이지 않고 해당 사용자 스토리가 실질적으로 사용자에게 가치를 주는 것인지 아닌 지에만 집중했습니다. 사용자 관점에서 사고하면서 사용자 입장에서 가치를 전달받는 것이라면 스토리 포인트를 부여하고 그렇지 않은 경우는 0 스토리 포인트로 관리했습니다. 또한 사용자 스토리는 더 이상 나눌 수 없을 정도로 작게 나누어서 관리했습니다. 예로 ‘LINE Pay 일반 사용자는 로그인과 로그아웃을 할 수 있어야 한다.’를 ‘로그인’, ‘로그아웃’으로 나누는 것입니다. 사용자 스토리를 효과적으로 작성할 수 있는 기법인 INVEST에서 말하는 Independent와 Small 원칙에 충실히 따른 것입니다.

 

기준 사용자 스토리 설정

스토리 포인트를 적용했던 시점은 LINE Pay 서비스를 제공한 지 4~5년이 지난 시점이라 기준 사용자 스토리를 정하는 것이 어려웠습니다. 그래서 다음과 같이 접근했습니다.

  • 앱 개발 팀에서의 기준: 서버 API 통신 없이 UI(user interface) 엘리먼트를 특정 조건에 따라 화면에서 제어하는 것(노출 혹은 비노출, 확대 혹은 축소 등).
  • 서버 개발 팀에서의 기준: 새로운 API로 특정 조건에 맞는 단순한 정보를 제공해 주는 것.

위 기준은 사용자 스토리에 맞지 않는, 제공자 입장에서의 기능 설명인 것처럼 보이는데요. 실제로 스토리를 이렇게 작성하지는 않습니다. 스토리 포인트를 추정할 때 해당 사용자 스토리가 위와 같은 기준을 만족한다면 1 스토리 포인트 정도라고 접근할 수 있게 방식을 제공한 것입니다. 이와 같은 접근 방식으로 이를 만족하는 여러 개의 기준 사용자 스토리들이 선정되었고, 이를 기반으로 스토리 포인트가 인플레이션되지 않도록 아래와 같이 스토리 포인트 레퍼런스 테이블을 생성해 유지하고 관리했습니다.

 

스토리 포인트 추정 및 부여

위에서 잠깐 설명한 것처럼 LINE Pay에서 스토리 포인트를 할당할 수 있는 사용자 스토리는 사용자에게 실질적인 가치(value)가 전달되는 것으로만 한정했습니다. 실제 대다수의 애자일 관련 전문가들이 제안하는 방법이기도 합니다. 사용자에게 실질적인 가치가 전달된다는 것은 사용자에게 해당 기능이 전달되어 사용자가 실질적으로 이용한다는 뜻입니다. 예를 들어 로그인 사용자 스토리를 구현해 전달하면 사용자는 로그인을 할 수 있는데요. 이 부분이 스토리 포인트를 할당할 수 있는 사용자 스토리입니다. 사용자에게 실질적인 가치가 전달되는 것에만 스토리 포인트를 부여하면, 팀원들의 사고에 조그마한 전환이 발생합니다. 이는 팀이 벨로시티를 높이기 위해 사용자에게 가치가 있는 일들을 찾아서 수행할 확률을 높여 줍니다.

 

스토리 포인트 추정

스토리 포인트를 추정하기 위해 사용자 스토리에 대해 설명하고 논의할 때 약간의 기술적 배경지식을 포함하기로 했습니다. 기술적 배경지식은 사용자 입장에서 이해할 수 있는 지식 정도로 한정했고, 사용자가 알 수 없는 내부 구조에 대한 기술 지식은 배제했습니다. 예로 서버 개발 팀이 특정 사용자 스토리를 구현하기 위해 2개의 API를 제공한다면 다음과 같은 기술 정보만 포함하기로 했습니다.

“2개의 API를 제공해야 한다. A API는 정보 전달을 수행한다. B API는 정보 갱신을 수행한다.”

아래와 같은 상세한 기술 설명은 하지 않기로 했습니다.

“A API가 정보를 전달할 때 C 시스템의 API와 특정 데이터베이스에 있는 데이터를 조합하여 전달해야 한다.”

 

스토리 포인트에 피보나치수열 사용

LINE Pay에서는 스토리 포인트로 피보나치수열을 응용한 수열을 사용하고 있습니다. 피보나치수열을 사용하는 이유는 피보나치수열 자체가 불확실성을 포함한 수열이기 때문입니다. 피보나치수열은 처음엔 앞 숫자와의 간격이 크지 않지만, 뒤로 갈수록 점점 앞 수와의 간격이 커집니다.

  • 1, 2, 3, 5, 8, 13, 21, … : 1에서 3까지는 앞 수와의 차이가 1밖에 되지 않지만 3부터는 앞 수와의 차이가 점점 커짐

이는 큰 스토리 포인트를 할당한 사용자 스토리에는 예측하기 어려운 여러 가지 변수가 있다는 것을 간접적으로 나타냅니다. 예로 사용자 위치 기반으로 1.5km 이내에 있는 LINE Pay 가맹점을 지도에 표시하는 사용자 스토리를 추정한다고 할 경우, 이 사용자 스토리는 로그아웃 사용자 스토리에 비해 얼마나 어려운 스토리가 될까요? 아무래도 여러 가지 많은 사항들을 고려해야 할 것 같습니다. 위치 기반 탐색을 지원하는 프레임워크가 LINE Pay 플랫폼에 이미 제공되고 있는지도 모르겠고, 그 외에도 여러 가지 의문점이 생깁니다. 이런 경우에 피보나치수열이 아닌 일반 자연수를 늘어놓은 등차수열을 사용하면 6, 7, 8, 9, 10 등 다양한 값이 나올 수 있을 것입니다. 하지만 피보나치수열을 사용한다면 5나 8, 13, 이 세 가지 수 중 하나로 수렴할 확률이 높고, 해당 수열 간격이 큰 만큼 불확실성을 포함하고 있다고 쉽게 파악할 수 있습니다. 또한 이렇게 큰 스토리 포인트에 내재된 불확실성을 해소하기 위해 13 이상의 사용자 스토리는 더 세분화해 관리할 수 있도록 지속적으로 조정합니다. 13 스토리 포인트인 A 사용자 스토리는 추가 검토 후 다음과 같은 세 개의 사용자 스토리로 재 도출할 수 있습니다.

  • B 사용자 스토리: 5 스토리 포인트
  • C 사용자 스토리: 5 스토리 포인트
  • D 사용자 스토리: 5 스토리 포인트

총 15 스토리 포인트로 스토리 포인트가 더 커졌지만 세 개의 사용자 스토리로 분해되면서 불확실성이 제거됐다고 간주할 수 있습니다.

 

스토리 포인트 부여 여부 결정 – 리팩토링과 디버그

리팩토링에도 스토리 포인트를 부여할까요? 다음과 같은 리팩토링은 어떨까요? ‘패스코드 관련 코드가 매우 복잡하여 리팩토링을 해야 함.’ 이는 사용자 스토리로 적합하지 않을뿐더러 스토리 포인트를 할당해야 할 대상으로도 적합하지 않습니다. 그 이유는 패스코드 관련 코드를 리팩토링한다고 하더라도 실제 사용자가 패스코드를 사용하면서 얻는 가치는 리팩토링하기 전과 동일하기 때문입니다. 저 같은 경우 위와 같이 별도 작업으로 리팩토링을 진행하는 것을 기술적인 부채(technical debt)를 갚는 것이라고 간주합니다. 리팩토링도 사용자 스토리를 구현하면서 같이 진행해야 하는 작업입니다. 이러한 것들이 모두 포함되어 있는 것이 스토리 포인트입니다. 지속적인 개선 없이 결과에만 집중하다가 결국 더 이상 그대로 둘 수 없는 상황에까지 와서야 별도 작업으로 진행한다는 것은 그동안 추가 스토리 포인트를 공짜로 얻었기 때문이니 이를 갚는 행동으로 보는 것입니다. 리팩토링과 비슷한 유형으로 디버그는 어떨까요? 디버그도 0 스토리 포인트입니다. 버그를 해결하는 것도 기술적인 부채를 갚는 행위 중의 하나입니다. 로그인 사용자 스토리를 구현해 전달했는데 로그인 관련 버그가 발견되어 이를 해결한다는 것은 로그인 사용자 스토리를 구현할 때 잘 처리했어야 하는데 그렇지 못했기 때문에 기술 부채를 갚는 것으로 간주해 0 스토리 포인트를 부여합니다.

이 두 가지 사례를 보니 다음과 같은 결론을 쉽게 내릴 수 있습니다. ‘별도로 리팩토링 작업을 하지 않도록 평소에 리팩토링을 지속적으로 진행하고, 버그가 생성되지 않도록 꼼꼼하게 구현한다면 리팩토링이나 버그 해결할 시간에 사용자에게 가치 있는 다른 일을 진행할 확률이 높아질 것이고, 그렇다면 팀의 벨로시티도 향상될 것’이라는 결론입니다. 그런데 이와 같이 리팩토링이나 버그에 0 스토리 포인트를 부여해 진행할 때 역효과가 발생할 수 있습니다. 다음과 같은 상황을 생각해 보겠습니다. 스프린트가 종료된 후 A 개발자는 10 스토리 포인트를 획득했는데 B 개발자는 0 스토리 포인트를 획득했습니다. 자세히 확인해 보니 A 개발자는 별다른 어려움 없이 사용자 스토리 구현에 집중할 수 있었지만, B 개발자는 특정 사용자 스토리를 구현하기 위해서 퇴사한 C 개발자가 만들어 놓은 기능을 꼭 리팩토링해야 했고, 그 때문에 0 스토리 포인트를 획득한 경우입니다. 이런 경우 B 개발자의 의욕이 저하될 수 있습니다. 분명 일을 하지 않은 것은 아니지만 스토리 포인트 수치를 보면 자신이 아무것도 안한 것처럼 보일 수도 있기 때문입니다. 따라서 이런 오해가 발생하지 않도록 팀원들과 충분한 공감대를 만들어야 합니다. 스토리 포인트는 개개인을 평가하기 위한 도구가 아니며 팀이 사용자에게 가치 있는 일을 하기 위해 어떻게 나아가고 있는지를 보여주는 팀을 위한 수치라는 충분한 공감대를 조성해야 합니다.

 

스토리 포인트 부여 여부 결정 – 데이터 추출

LINE Pay 서비스를 운영하다 보면 외부 팀에서 전략 계획을 위해 데이터 추출을 요청하는 때가 많습니다. 이런 데이터 추출 작업도 스토리 포인트를 부여하면서 운영하는 것이 좋을까요? LINE Pay에서는 이와 같은 작업도 스토리 포인트를 부여하고 운영하기로 했습니다. 단, 다음과 같은 기본 룰을 설정했습니다.

  • 새로운 유형의 데이터 추출 건이라면 해당 건의 어려움을 추정한다.
  • 이전에 추출해 주었던 데이터를 기간만 변경하여 다시 추출하는 것이라면 0 스토리 포인트를 부여한다.

이와 같이 운영한 이유는 데이터를 추출함으로써 외부 팀이라는 사용자가 해당 가치를 얻기 때문입니다. 그렇기 때문에 스토리 포인트 부여 대상으로 운영했습니다. 단, 일자만 변경한 데이터 추출 요청 건을 또 받았다면 그때는 최초의 요청을 참조해두고 0 스토리 포인트로 관리합니다. 이미 첫 요청을 처리하면서 가치를 창출할 수 있는 방법을 만들었기 때문에 이후 요청 건은 기존 방법을 지속적으로 사용하는 것으로 간주할 수 있기 때문입니다.

다음과 같은 예시를 생각하면 될 것 같습니다. LINE Pay 사용자가 특정 기간 동안 자신의 결제 이력을 볼 수 있도록 결제 이력 내역 기능을 제공했습니다. 사용자는 이제부터 원하는 기간을 변경하며 결제 이력을 확인할 수 있습니다. 데이터 추출 건도 결제 이력 내역과 같은 역할을 수행하는 쿼리를 만들어 사용자에게 제공한 건이라고 이해하면 됩니다. 사용자에게 이미 전달한 기능으로 사용자가 매번 날짜를 변경해 사용한다고 해서 스토리 포인트를 얻는 것이 아닌 것처럼, 데이터 추출 건도 날짜를 변경해 데이터 추출을 제공한다고 하여 매번 지속적으로 스토리 포인트를 제공하는 것은 아닙니다. 

부가적으로 데이터 추출과 관련하여 좋은 방법이 있습니다. 동일한 데이터 추출을 특정 조건만 변경해 지속적으로 요청하는 경우엔, 해당 데이터를 쉽게 추출할 수 있는 툴을 제공하는 것이 팀의 벨로시티를 높이는 데 더 좋습니다.

 

스프린트 데이터 공유

스프린트 데이터는 팀원 간 서로 오해가 생기지 않게, 그리고 좋은 방향으로 나아갈 수 있도록 항상 쉽게 공유할 수 있게 관리해야 합니다. LINE Pay에서는 아래와 같이 스토리 포인트뿐만 아니라 해당 스프린트에서 처리했던 버그 이슈 개수와 최종 사용자 응대 요청 개수, 스토리 포인트가 할당되지 않은 이슈 처리 개수 등 여러 가지를 같이 기록하고 관리하면서 벨로시티를 점검하고 있습니다.

위 데이터에서 0914-0925 스프린트와 비교하여 1012-1023과 1026-1106 스프린트에선 획득한 스토리 포인트가 적어지는 것을 볼 수 있습니다. 대신 1012-1023과 1026-1106 스프린트에서는 버그나 문의와 관련된 이슈 개수가 급격하게 높아지고 있는 것으로 보입니다. 그렇다면 왜 버그가 많이 생성됐는지 왜 갑자기 문의가 많아지고 있는지 등을 분석하고 개선한다면 스토리 포인트를 획득하는, 즉 사용자에게 가치 있는 일을 하는 데 더 집중할 수 있을 것으로 보입니다.

또한 이런 데이터는 팀을 위한 데이터이지 개개인을 평가하거나 각 팀별 생산성을 상호 비교하고 평가하기 위한 데이터가 아닙니다. 그런 방향으로 활용해서는 안 됩니다.

데이터를 수집하다 보면 결국 위와 같이 각 개인이 획득한 스토리 포인트를 확인할 수 있습니다. 매니저 입장에선 위 데이터를 활용하고자 하는 욕구가 생길 수 있는데 절대로 그래서는 안 됩니다. 위에서도 말씀드렸듯이 스토리 포인트는 팀을 위한 수치입니다. 팀이 어떤 상태에 있고 얼마나 움직일 수 있는지를 나타내는 지표입니다. 이를 개개인을 평가하기 위한 도구로 활용하기 시작한다면 본래의 가치가 훼손되어 스토리 포인트 인플레이션 같은 현상이나 팀원들의 사기 저하와 같은 악영향이 나타날 수 있습니다.

또한 스토리 포인트는 각 팀의 고유 속성에 맞춰 단위가 형성되기 때문에 스토리 포인트로 각 개별 팀을 비교할 수도 없습니다. 이는 위에서도 말씀드린 부분입니다. 만약 어떤 팀의 벨로시티가 점진적으로 올라가서 확인해 보니 스토리 포인트 인플레이션이 아닌 내부 프로세스 개선으로 벨로시티가 높아진 거라면, 이런 프로세스를 다른 팀에도 적용해 효과를 확인하고, 효과가 있다면 이를 지속적으로 다른 팀에 적용해 나가는 방식으로 스토리 포인트를 활용해야 합니다.

 

맺으며

제가 말씀드리고자 하는 부분이 잘 전달됐을지 모르겠네요. 한 번 더 요약해 봅니다.

  • MD와 스토리 포인트는 다르다.
    • 스토리 포인트는 작업자와 시간과 별개로 사용자 스토리 그 자체의 어려움을 나타내는 값이다.
  • 스토리 포인트를 부여하는 기준은 팀원들과 합의하여 결정한다.
    • 즉, 스토리 포인트는 팀을 위한 값의 단위이다.
  • 스토리 포인트는 정밀성을 뜻하지 않는다.
    • 스마트하면서 민첩하게 추정할 수 있는 수단을 제공하는 것이다.
  • 스토리 포인트는 사용자에게 가치 있는 것에만 부여한다.
  • 스프린트에 계획된 스토리 포인트 모두를 획득하는 것이 목적이 아니다.
    • 스프린트에 획득한 스토리 포인트로서 팀의 현재 상태를 점검하는 것이 목적이다.

또한 아래와 같은 사항에 주의해야 합니다.

  • 시간에 대입해 스토리 포인트를 추정하지 않는다.
  • 스토리 포인트에 인플레이션이 발생하지 않도록 지속적으로 관리한다.
  • 스토리 포인트를 개개인 또는 팀별 비교 평가 도구로 사용하지 않는다.

이번 글이 스토리 포인트 활용의 모든 것을 완벽하게 설명하고 있는 것은 아닙니다. 그렇기 때문에 관심 있는 분들은 개별적으로 더 학습해 보시길 권장합니다. 사실 사용자 스토리만으로도 내용이 매우 방대한데요. 이 글에서 매우 짧게 설명했기 때문에 오해가 생기진 않을까 우려됩니다. LINE Pay의 사례가 100% 옳은 방향이 아닐 수 있습니다. 하지만 사용자 스토리와 스토리 포인트의 본질에 맞게 행동하기 위해 많은 노력을 기울이고 있습니다. LINE Pay 개발 팀에서는 “사용자에게 의미 있는 가치를 전달하기 위해 우리 팀은 어떻게 움직여야 하는가?”를 지속적으로 확인하고 개선하기 위해 스토리 포인트를 활용하고 있습니다. 그런 부분에서 영감을 얻어 스토리 포인트를 팀에 어떻게 적용하고 활용할 것인지 방향을 찾길 바랍니다. 간혹 형식에 치우쳐 본질을 간과하고 모든 것을 폄하하는 경우가 있는데요. 그런 부분을 환기시키고자 아래 메시지를 마지막으로 이 글을 끝맺어 봅니다.

형식에 얽매이지 말고 본질에 맞추어 움직이자.