見積りをお願いされた時のはなし
「とあるシステムのフロントエンド部分を ● 月 ● 日までにリリースしたいけど、できますか?」と相談された。 実際にどの様な観点でどの様に見積りを実施したかまとめる。
前提
- 新しいプロジェクト
- フロントエンドは 1 スプリントのみが終わったタイミング
- 紙芝居を作成して、UI コンポーネントを複数作成してデプロイした状態
- フロントエンドは 1 スプリントのみが終わったタイミング
- 弊チームのスプリントは 2 週間としている
- 2 週間毎にリリース or デプロイをしている
- タスク管理には GitHub を利用している
ベロシティの計測を始めたばかりで有用な平均値を出せていない状態ではあるが、システム全体の計画に関わるため不確実性が高くても見積りをしてほしいとのことだった。
※ 以下の手順は文書用に加工しているので実際に行った見積りとは少々異なる。
手順
ざっくりとまとめると、機能を実現するために必要な作業を細分化し、それに対してストーリーポイントを付与する。
過去のベロシティを元にマイルストーンに当てはめていくと、何がいつまでに終わるか見積りができる。
大分類となる機能 issue を作成
機能(= ページ)が 9 つあったので、大分類となるそれぞれの issue を作成した。
. ├── 機能 A ├── 機能 B └── ...etc
各機能の UI コンポーネントを定義
それぞの機能毎に、必要なコンポーネントを定義し、コンポーネント実装用の issue を作成する。 今回は既に作成していた紙芝居を元に定義を行った。
この時点で機能の優先順をステークホルダーに確認しており、優先度の高い機能から実施した。
機能毎に大幅に UI が変わらない場合は、後に着手する機能になるほどコンポーネントの定義数は減ってくるはず。
各コンポーネント実装 issue にストーリーポイントを付与した。
弊プロジェクトでは、1 度目のスプリントで作成したシンプルなコンポーネント実装のタスクを 1 ポイントとした。これについては作業量・複雑さの共通認識がとれていた。と思っている。 ちなみに、ストリーポイントはフィボナッチ数で粗いポイントにしている。
. ├── 機能 A │ ├── Button コンポーネント(1pt) │ ├── List コンポーネント(1pt) │ ├── SelectBox コンポーネント(1pt) │ ├── CheckBox コンポーネント(1pt) │ └── ...etc ├── 機能 B │ ├── Pagenation コンポーネント(2pt) │ └── Accordion コンポーネント(2pt) └── ...etc
各機能のページ実装を考える
次に各機能のページを表示するために必要な実装 issue を作成した。このタスクの責任はページを表示することで、以下の様な TODO を持っている。 (実際に作業に着手する前に issue を細かく分割して対応する)
- UI コンポーネントを組み合わせる
- API を実行してデータをコンポーネントに注入する
- 状態を持つ必要があればそれを管理するためのロジックを実装する
- Cypress で自動テストをしているので、それの実装をする
例によって、各機能毎に必要な TODO を洗い出した上でストーリーポイントを付与した。
. ├── 機能 A │ ├── Button コンポーネント(1pt) │ ├── List コンポーネント(1pt) │ ├── SelectBox コンポーネント(1pt) │ ├── CheckBox コンポーネント(1pt) │ ├── ページ実装(2pt) │ └── ...etc ├── 機能 B │ ├── Pagenation コンポーネント(2pt) │ ├── Accordion コンポーネント(2pt) │ └── ページ実装(3pt) └── ...etc
機能を実現するために必要なロジックを想像する
UI コンポーネント実装とページ実装以外に必要なロジックの実装がないかを機能毎に洗い出した。
多くの機能は以下の様な TODO になった。
- 詳細設計をする
- ページやコンポーネントが期待する型を定義する
- パッケージ間のインターフェースを決める
- パッケージ間の依存関係を整理する
- API を実行し、ページやコンポーネントが期待する型へコンバートする関数を作成する
- 機能特有のバリデーションロジックを実装する
これもストーリーポイントを付与した。
. ├── 機能 A │ ├── Button コンポーネント(1pt) │ ├── List コンポーネント(1pt) │ ├── SelectBox コンポーネント(1pt) │ ├── CheckBox コンポーネント(1pt) │ ├── ページ実装(2pt) │ ├── ロジック実装(3pt) │ └── ...etc ├── 機能 B │ ├── Pagenation コンポーネント(2pt) │ ├── Accordion コンポーネント(2pt) │ ├── ページ実装(3pt) │ └── ロジック実装(3pt) └── ...etc
開発環境の改善タスクを考える
現時点である不満や、プロジェクトを効果的に進めるために改善したいと思っている作業を issue として起票した。
直接的な成果物はないが、プロジェクトを効果的に進めるために必要だと思うタスク。
. ├── 機能 A │ ├── Button コンポーネント(1pt) │ ├── List コンポーネント(1pt) │ ├── SelectBox コンポーネント(1pt) │ ├── CheckBox コンポーネント(1pt) │ ├── ページ実装(2pt) │ ├── ロジック実装(3pt) │ └── ...etc ├── 機能 B │ ├── Pagenation コンポーネント(2pt) │ ├── Accordion コンポーネント(2pt) │ ├── ページ実装(3pt) │ └── ロジック実装(3pt) ├── パッケージ更新の自動化(1pt) ├── リリースフローの改善(2pt) └── ...etc
マイルストーンに落とし込む
本来ならスプリントを複数回経験し、ある程度平均値が確認できたベロシティをもとに決めたいが... 以下の様にスプリント毎に対応範囲を決定した。
※ チームが 1 回のスプリントで約 5pt 分消化できると予想している(実際のベロシティとは異なる)
※ 「..etc」としているところは考慮していない
- スプリント 1 回目
- スプリント 2 回目
- 機能 A
- ページ実装(2pt)
- リリースフローの改善(2pt)
- 機能 A
- スプリント 3 回目
- 機能 A
- ロジック実装(3pt)
- 機能 B
- Pagenation コンポーネント(2pt)
- 機能 A
- スプリント 4 回目
- 機能 B
- Accordion コンポーネント(2pt)
- ページ実装(3pt)
- 機能 B
- スプリント 5 回目
- 機能 B
- ロジック実装(3pt)
- 機能 B
ここまでしておけば、
「とあるシステムのフロントエンド部分を ● 月 ● 日までにリリースしたいけど、できますか?」
の ● 月 ● 日がスプリント 3 回目のリリース日であったとしても、「機能 A は対応できるが、機能 B は間に合いそうにない」と回答できる(実際に近い対応を行なった)。
頑張って間に合わせます!ではなく、現状のリソースでできることを伝えて、ステークホルダーが対応範囲を縮小するか・期限をのばずか等の検討をするための材料を共有することができた。
今後
2 週間毎に見積りを見直して、適切に共有・相談していこうと思う。