1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

スクラム開発におけるストーリーポイント設定の極意

1
Last updated at Posted at 2021-08-26

はじめに

この記事では、スクラム開発において重要な要素の一つであるストーリーポイントについて解説する。

タイトルに「極意」という仰々しいワードを入れているが、筆者が個人的に感じていることや考えていることも含まれるため、参考程度に読んでほしい。

ストーリーポイントとは

あるタスクを完了させるために必要な工数を表す指標の一つである。タスク A は 3 ポイント、タスク B は 5 ポイント、のように設定していく。

ストーリーポイントの配分方法について

これと言った決まりはないが、よく使われる配分として、フィボナッチ数列が挙げられる。

フィボナッチ数列とは、前の項 (数字) とさらにその前の項を足し算した結果が次の項になる数の並びである。

[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...]

たとえば、13 という数字は、一つ前の 8 とそのさらに一つ前の 5 を足し算した結果である。

なぜフィボナッチ数列を使うのか

一つ前の数字と大きくかけ離れるため、ポイントの設定に迷ったりすることが少ないから、というのが理由として挙げられる。

たとえば、タスク A があり、ストーリーポイントの配分に 1315 という選択肢があったとき、このタスクのストーリーポイントを 13 にすべきなのか 15 にすべきなのかは迷うことが多い。

しかし、1321 くらい数字が離れていれば、13 か 15 で迷っていたタスク A に 21 を割り振るのは感覚的に乖離が大きいと気づく。

そうなった場合に、迷うことなく 13 を設定できるかもしれないし、もし 13 よりも少し大きい数字 ― 15 くらい ― にしたいという気持ちがまだ残っているのなら、それはタスクの粒度がまだ粗い可能性がある。

たとえば、タスク A を、タスク α, β, γ に細分化することによって、γ は、α と β の実装によってはもしかしたら対応不要かもしれない、と気づくかもしれない。そうなると、α と β のストーリーポイントは明らかになり、ブレが少なくなる。

そうやって少しずつ精度を上げていくことができる。

ストーリーポイントは時間見積もりではない

タスクを完了させるために必要な工数だから、3 ポイントだから 3 時間かかる、5 ポイントだから 5 時間かかる、という指標ではない。

これはあとでも説明するが、ストーリーポイントは相対評価 である。タスク A が 2 ポイントで、タスク B が 8 ポイントだった場合、B の工数は A の工数の 4 倍あると見積もることができる、という指標である。

ストーリーポイントはチーム全体の指標

一般的に、ストーリーポイントはチーム全体の指標として用いられる。個人の力量に依存しない。

これはどういうことかというと、たとえば、チーム内にスーパーエンジニア (優秀なエンジニア) と入ってきたばかりの新米エンジニアがいたとする。タスク A は、スーパーエンジニアにとっては簡単だからストーリーポイントは 5 だが、新米エンジニアにはまだ難しいから 13 にする、といった決め方はしない。

あくまで、そのチーム全体で、そのタスクがどれくらいの開発コストで完了するのかを基準に採点する。だから、似たような機能実装でも、会社 A のチームではストーリーポイントが 5 で、会社 B では 8 になるかもしれない。それはそれで問題ない。

筋トレに例えられる

ストーリーポイントが時間見積もりではないことと、個人の力量に依存しないことを示す例えとして、筋トレがわかりやすいのではないかと思う。

20 kg のダンベルを持ち上げることを考える。筋肉ムキムキの街雄さんは軽々と 100 回連続で持ち上げられるが、最近太り気味のひびきさんは 1 回持ち上げるのがやっとだ。

この場合、20 kg というダンベルの負荷が、ストーリーポイントに相当し、何回持ち上げられるかがタスク完了までの時間に相当する。

誰が持ち上げたとしても 20 kg というダンベルの重さは変わらない。街雄さんが持ち上げると 5 kg 分になるから、100 回連続で持ち上げられる、ということにはならない。同じ重量でも人によって連続で持ち上げられる回数が異なるのは、筋肉量が違うからだ。

ここでいう筋肉量が個人の能力や知識量に相当するもので、能力や知識量が多ければ多いほど、他の人よりも早くタスクを終わらせることができる可能性が高い。

まとめると以下の通りだ。

筋トレ スクラム開発 補足
ダンベルの重量 ストーリーポイント 人によって変わるものではない
何回連続で持ち上げられるか タスク完了までの時間 こなせる量
筋肉量 能力・知識量 人によって個人差がある

ストーリーポイントはみんなで決める

上述の通り、ストーリーポイントはチーム全体の指標のため、そのタスクや案件を進めるエンジニアだけで決めるわけではない。

タスク A があり、そのタスクのメイン担当者が太郎さんだった場合、太郎さんを含めたチーム全員でタスク A のストーリーポイントを推定し、妥当なポイントを設定する。

各々の決めたストーリーポイントをチームに公開する際には、プランニングポーカー がよく用いられる。

プランニングポーカーとは

チーム全員でストーリーポイントを設定する際の手法である。

以下の手順で行う。ポイントの配分方法にフィボナッチ数列を採用しているものとする。

  1. 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... と書かれたカードを人数分用意する
  2. チーム全員にそれぞれ 1 枚ずつカードを配る (チームは手札として持ち、他の人には見えないようにする)
  3. 一つのタスクに対し、各々がストーリーポイントを頭の中で設定する (この時点では他の人にはその数字を言わない)
  4. 全員が設定をし終わったことを確認し、全員で同時にストーリーポイントと同じ数字の書かれたカードを場に公開する
  5. 各タスクごとに 1 〜 4 を繰り返す

プランニングポーカーのメリット

「こんなことをしなくても、『このタスクはこれくらいだと思う』と各々が言っていけば良いじゃないか」

はじめは誰しもそう思うだろう。

しかし、一人が ― とりわけ声 (チーム内の発言力) が大きい人が ― 最初にストーリーポイントをチーム内に公表してしまうと、他の人がそれに流されてしまう可能性がある。以下のような理由で。

(そのタスクに対して関心がないなあ……)

(この人がこう言っているんだからきっとそれが正しいんだろう……)

(めんどくさいから自分もそう言うことしよう……)

(自分の考えていたストーリーポイントは、他の人と全然違う…… 同調圧力が怖いから言えない……)

このような理由で自分が考えていたストーリーポイントがチーム内に共有されず、結局 1 〜 2 人の意見のみが反映されてしまうことがある。それではチーム内でストーリーポイントを決定しているとは言い難い。

このような状況を防ぐために、みんなで一斉に意見 (ストーリーポイント) を公表できるプランニングポーカーがしばしば用いられる。

オンライン版プランニングポーカー用ツールやサービスもある

本来、プランニングポーカーは全員が同じ場所 (会議室等) に集合してオフラインで行うものだが、最近はリモートワークの需要も増え、オンラインでできる Web 版プランニングポーカーツールやサービスも登場してきている。

Plapo

必ずしもオフライン版のプランニングポーカーの形式にこだわる必要はないので、そこはチーム内で話し合い柔軟に対応すると良いだろう。

ストーリーポイントは相対評価

タスクの見積もりに正解はなく、このタスクは絶対にこのストーリーポイントである、といったことは言えない。だからこそ、基準となるタスクを用意 し、相対的に評価することが重要である。

たとえば、ユーザの検索機能を実装することを考える。users テーブルには、ID や性別、誕生日のカラムが入っている。

性別による検索機能のタスクのストーリーポイントが 2 だったとしたら、ID による検索も、相対的に同じくらいのストーリーポイントで実装できるだろうと判断できるかもしれない。あるいは複数 ID でも検索できるようにするなら、複数の ID を配列に格納して SQL を発行する必要があるので、少し増えて 3 になるかもしれない。

また、年齢による検索機能を実装する場合、テーブル上には「年齢」を表すデータがないので、現在の日時と誕生日から逆算して検索する必要がある。そうなった場合は、誕生日から年齢を逆算するロジックを追加で実装する必要があるため、ストーリーポイントは 5 くらいになるかもしれない。

このように、何か基準となるタスクがあり、そのタスクのストーリーポイントから相対的に判断すると、見積もりがしやすいし、精度も高くなる。

導入当初は、基準となるタスクが少なく見積もりが難しいと感じるかもしれない。しかし、導入してしばらく運用を続けていると、次第にこのタスクはこれくらいのストーリーポイントだと判断できるようになってくる。過去のいくつかのタスクで「実績」が蓄積したことにより、見積もりのしやすさと精度が上がってくる。

ストーリーポイントよりタスクの細分化が重要

これは個人的な見解だが、ストーリーポイントを如何に正確に推定するかよりも、タスクを如何に細分化できるかのほうが重要 だと筆者は考えている。

これは例を見たほうがわかりやすい。

ダメな例

  • 89 ユーザ検索機能の実装

89 はストーリーポイントを表している。

まず大前提として、これだと、何を根拠に 89 というストーリーポイントを算出したのかが全くわからない。

そして、どこに時間がかかりそうなのかもわからない。ユーザからの入力値をバリデーションするところなのか、入力値を整形するところなのか、あるいはテストを書くところなのか。

どこの実装にどれくらいかかるかが明確ではないということは、想定外のコストがかかりやすい。たとえば先の例で、年齢は誕生日から逆算するロジックが必要だと述べたが、細分化していないと気づきづらい。

「ID 検索でストーリーポイント 3 くらいで、全部で項目が 27 だから、合計 81 ポイント! 少し余裕を持たせてフィボナッチ数列に当てはめると 89 ポイント!」

のように細分化せず概算で決めてしまうと、年齢検索のように単純なロジックでは実装できない部分で想定外の時間がかかってしまい、予定通りに案件を達成できない可能性が出てくる。

また、別の案件として別のテーブルの検索機能を実装することになった場合に、ユーザ検索機能の実装が 89 ポイントだったから、今回も 89 ポイントくらいで大丈夫だろう、と判断するのが危険なことは、よもや言うまでもないだろう。

一応補足として、ストーリーポイントはあくまで指標であり、これくらいのストーリーポイントを設定したから必ずこの期間で完了する、ということを確約するものではないし、過信しすぎるのは良くない。

だが、1 〜 2 ヶ月で終わるとみられていたものが、実際にやってみたら半年もかかってしまったとなると、タスクの細分化や見積もりの精度が甘いことを指摘せざるを得ないだろう。

好ましい例

  • 100 ユーザ検索機能の実装
    • 8 ID 検索
      • 2 ORM を用いた SQL の組み立てロジックの実装
      • 2 ユーザ入力値の整形
        • 1 全角数字を半角数字に変換
        • 1 複数指定の場合、カンマ区切りでもスペース区切りでも配列に変換
      • 1 ユーザ入力値のバリデーション
      • 3 テスト
        • 1 複数 ID で検索できる?
        • 1 数字じゃない値が来た場合に弾いている?
        • 1 全角数字が混ざっていた場合に対応できる?
    • 5 性別検索
      • 2 ORM を用いた SQL の組み立てロジックの実装
      • 1 ユーザ入力値のバリデーション
      • 2 テスト
    • 12 年齢検索
      • 4 ORM を用いた SQL の組み立てロジックの実装
        • 2 誕生日から年齢を逆算するロジックの実装
        • 2 範囲検索によるデータ型変換処理 (例: 12 歳 〜 34 歳までの人を全員検索)
      • 1 ユーザ入力値の整形
        • 1 全角数字を半角数字に変換
      • 1 ユーザ入力値のバリデーション
      • 6 テスト
        • 2 誕生日から年齢を算出するロジックは正しいか?
        • 2 範囲指定のロジックは正しいか?
        • 1 数字じゃない値が来た場合に弾いている?
        • 1 全角数字が混ざっていた場合に対応できる?
    • 10 リファクタリング
      • 3 各検索項目をメソッドに分割
      • 5 検索ロジックの責務を controller や model から切り離す
      • 2 Linter の警告修正
    • ...
      • ...
      • ...
      • ...

上記のように細分化すると、いろいろなことが見えてくる。たとえば、以下のようなことがわかる。

  • ID 検索は、全角数字を半角数字に変換してほしいという要望や複数 ID での検索ができるようにしてほしいという要望がある
    • → 半角数字への変換処理やデリミタの文字列処理が必要な分、入力値の整形に関して他よりストーリーポイントが多くなる
  • 性別検索は、入力形式が HTML のラジオボタンだから、ユーザの入力値の整形はいらないだろう
    • → 他の検索項目よりもその分、合計のストーリーポイントが少なくなる
  • 年齢検索は、年齢のデータが DB にないので、誕生日から逆算するロジックが必要になる
    • → SQL の組み立てのロジックの実装に関して他よりストーリーポイントが多くなる

このようなことがわかってくることで、以下のメリットがある。

  • 想定外の工数がかかるリスクが減らせる
  • タスクの進捗具合も把握しやすい
  • その日その日でやるべきことが明確になるので、タスクが進めやすい
  • 目に見えてタスクが消化されていくのがわかるので、大きな案件でも開発のモチベーションが保ちやすい

上記はあくまで例なので、ここまで細分化しなくても良いかもしれない。反対に、もっと細分化したほうがタスクが進めやすいと思うなら、もっと細分化しても良いだろう。

細分化したタスクとそのストーリーポイントに関する補足説明を以下に示す。

  • 細分化したタスクを入れ子にするかどうかは任意だが、個人的には入れ子にしたほうがわかりやすいと感じているのでそうしている
  • 細分化した最小タスクのストーリーポイントをフィボナッチ数列で見積もり、同じ階層のタスクのストーリーポイントの合計値を一つ上の階層のストーリーポイントとしている
    • フィボナッチ数列ではないストーリーポイントが存在しているのはそのためである
  • チェックボックス付きでリスト化するとどこまで作業が進んでいるのかが把握しやすい

冒頭の繰り返しになるが、ストーリーポイントの正確さ以上に、タスクの細分化のほうが重要 だと筆者は考えている。ストーリーポイントはあくまで相対評価なので、多少なりとも精度のズレは往々にして発生する。

タスクをできる限り細分化できていれば、想定外の工数がかかるリスクが減らせるし、タスクの抽象度が下がることで見積もりもしやすくなる。つまり、タスクを細分化することで、ストーリーポイントの正確さは自ずと向上する と筆者は考えている。

想定外の出来事は常に起こりうる

注意してほしいのは、タスクを細分化すればするほど、基本的には想定外の工数はかかりにくくなるが、絶対にかからないというわけではない。

たとえば、年齢検索で、「12 歳以上」や「34 歳以下」のように、上限なしや下限なしでも検索できるようにすることを考える。

少し前の Ruby では、beginless range ((12..) で 12 以上の range を表現できる) や endless range ((..34) で 34 以下の range を表現できる) が実装されていなかったので、以下のように書く必要がある。

# 12 以上を表す
(12..Float::INFINITY)

# 34 以下を表す
(-Float::INFINITY..34)

実際には年齢ではなく誕生日から逆算するので、Date 型で範囲指定をしなければならない。

ところが、古いバージョンの Ruby では、Date 型の下限に -Float::INFINITY を指定することができないというバグがあった。

v2.5.7
(Date.today..Float::INFINITY)
# => #<Date: 2021-08-26 ((2459453j,0s,0n),+0s,2299161j)>..Infinity

(-Float::INFINITY..Date.today)
# ArgumentError (bad value for range)

ちなみに新しいバージョンの Ruby ではこのバグは修正されている。

当初、上記のような範囲指定で実装しようとしていた場合はここで躓いてしまう。この問題を解決する工数が新たに発生するだろう。

このことをすでに知っており、解決方法もわかっているスーパーエンジニアならここで想定外の工数が発生することはないだろうが、これを知らないエンジニアが、ストーリーポイント設定の段階で推定するのは困難だろう。

このような想定外の工数がかかることに対して、「仕方ない」の一言で片付けるのはお粗末かもしれないが、どのようなタスクにもこのような想定外の工数がかかることを考慮しておくのが良いだろう。

ストーリーポイントを会社の評価 (人事評価) に用いない

これは、チームリーダーのようなチームメンバーを評価する立場の人だけでなく、各チームメンバーにも覚えておいてほしい事柄である。

今まで説明してきた通り、ストーリーポイントは、時間見積もりでもなければ、個人の力量に左右されるものでもない。タスク A のストーリーポイントが 5 ポイントなら、それはチーム内の誰にとっても 5 ポイントだし、のび太くんが 3 日かかるとしても、出木杉くんには 1 日で終わるタスクかもしれない。

そこで気になってくるのが、人事評価に利用されないか、という点である。

ストーリーポイントを導入すると、よくも悪くも個々人のアウトプットが明瞭になりやすくなる。出木杉くんは四半期で 300 ポイント分のタスクを消化できたが、のび太くんは 100 ポイントしか消化できなかった、ということもわかるようになってくる。

ここで言いたいのは、個人の能力や力量を会社の評価に使ってはいけない、ということではない。あくまで その評価にストーリーポイントを直接的に介在させてはいけない、ということである。

単純にストーリーポイントの消化具合だけで人事評価をする人がチームリーダだった場合、何が起こるだろうか。筆者の頭の中には、このような会話が思い浮かぶ。

デビル出木杉くん: (ぼくがやるこのタスク、ふつうに見積もったら 5 ポイントだと思うけど、13 ポイントってことにしておけば、ポイントが稼げるな…… 😈)

のび太くん: (ぼくは要領が悪いし出木杉くんみたいに優秀じゃない……。ぼくがやるタスク、1 週間くらいかかりそうだけど 5 ポイントだから、また評価下がるかなあ…… 😢。13 ポイントくらいにしておいて欲しいなあ……)

デビル出木杉くん: 「ねえ、のび太くん。うちのチームリーダーはストーリーポイントの消化量でしか評価しないみたいだから、プランニングポーカーのとき、お互いのタスクをポイント高めにしてみない? そうすればぼくも君も、評価が良くなるよ!」

のび太くん: 「それいいね! ぜひそうしよう!」

デビル出木杉くん & デビルのび太くん: 😈😈😈😈😈

これは極端な例だが、このようにチームメンバー内での結託が起こらないとも限らない。仮に結託が起こらなかったとしても、自分が担当するタスクに対して、声を大きくして主張すれば、ポイントを意図的に上方に操作できるかもしれない。

これではストーリーポイントを設定している意味がなくなってしまう。尤も、チームリーダーが、人事評価の手段に用いるためにストーリーポイントをチーム内に導入しようとしているなら意味はあるのかもしれないが、これは本来の用途ではないし、チームとしても健全ではない。少なからずチーム内の生産性は下がるだろう。

上記の理由から、ストーリーポイントを直接的に人事評価に用いるのは避けるべきである。

まとめ

ここまで説明してきた中で重要なポイントをかいつまんでまとめる。

  • ストーリーポイントはタスクを完了させるために必要な工数を表す指標の一つ
  • ストーリーポイントは相対評価であり、時間見積もりではない
  • ストーリーポイントの配分方法に決まりはないが、フィボナッチ数列がよく用いられる
  • ストーリーポイントはチーム全体の指標であり、個々人の力量に左右されるものではない
  • ストーリーポイントをみんなで決める際は、プランニングポーカーを用いると良い
  • ストーリーポイントの採点よりも、タスクの細分化のほうが重要 (個人の見解)
  • どれだけタスクを細分化しても、想定外のことは起こりうると心得ておく
  • ストーリーポイントを人事評価に用いない

ストーリーポイントを導入し、上手に運用していくことで、以下のようなメリットが得られる。

  • 特定の期間 (例: 四半期) ごとにチーム内で達成できる案件の量をある程度正確に判断することができるようになる
    • → 期間内に達成できない量を割り振られて潰れてしまうことを防げる
  • やるべきことが明確になる
    • → チーム内の生産性を向上させることができる
  • 各人のタスクの進捗が可視化される
    • → 想定よりも日数がかかっているタスクに対して、他の人がヘルプに回ることができる

適切な運用方法を守って、チーム内を健全に機能させたい。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?