🌟

開発フローのざっくり概要

2021/07/22に公開

[前提]aiesec.jp を今後運用していく人に向けて

https://github.com/AIESEC-in-Japan/aiesecjp-web

今後HPを運用していく人に向けての資料を公開ドキュメントとしてここに残しておきます。
公開にした意図は、自分は一応外部の人で手伝っているだけなので内部資料に権限がないこともありますが、もしかしたらこれが役に立つ人もいるかも…という淡い期待を込めてです。

まず開発のフローがどんなものか分からないと思うので簡単に解説します。

本来あるべき姿を説明します。今の開発体制ではこのフローに則っているとは言えないです。
もし今後人材が充実させられるなら、本来あるべきフローに近づけられると良いと思います。

ここではそれぞれの工程についての詳細は書きません。
時間がある時に別で書きます。

本来あるべき開発フロー

流れを簡単に羅列します。
自分は普段アジャイル開発をしているので、アジャイルっぽい考え方かもしれません。
ここは人によって、チームによっても細かい部分は違うと思いますので、これだけが唯一の正解ではないです。(なんなら普段本業で開発してるものとも少し違います)

  1. 方向性の決定・課題特定
    1. なぜ、何のためにどんな手段で何をするのか
    2. 解決したい課題を特定・定義する。
  2. 要求定義
    1. 要求を明確にしておく。何が出来ればいいのか、どんな課題を解決したいのか。
  3. 要件定義
    1. 機能要件の定義
    2. 非機能要件の定義
    3. 計測要件の定義
    4. 適切な大きさにタスクを分解
  4. 開発計画
    1. 何を優先して着手するのかを決める
    2. SQCDのお話
  5. 開発の設計
    1. どうやって要件を満たすのか、HOWを決める
    2. 可用性、拡張性、パフォーマンス、セキュリティなども検討
  6. テスト設計
    1. 正常系、準正常系、異常系
    2. コードとして何が出来ればいいのか
    3. どんな品質を担保したいのかを設計する。
  7. 開発
    1. 実際に開発する
    2. 自動テストやlintを使い、開発時に発見できるバグは潰しておく。
  8. 検証・テスト
    1. 本番同様に非公開の環境で動作を検証する。
    2. 担保したい機能が担保できているのか、エラーが発生しないかなどの検証
    3. 事前に行ったテスト設計に従い、テストを実行する
  9. リリース
    1. テストもレビューも問題なければリリースを行い、本番に変更を適応する。
    2. リリース前テストとして、全機能のうち壊れていたらリリースできない機能のテストを行う。
  10. 公開
    1. 本番適応したら公開されます。
    2. しばらくはエラーがないかの確認と、できるなら本番環境を確認してみましょう。
  11. 効果検証
    1. 何かをリリースして終わりではなく、どの程度のユーザーがきているのか、期待通りに使ってくれているのかなどの検証を行います
  12. 分析と改修→1に戻る
    1. 検証データの分析結果と、全体の方向性に基づいて次の開発目標を定めます。

ざっくりフローが分かったところで

それぞれどんなことをするのか説明します。

方向性の決定・課題特定

なぜ何のためにこれを作る必要があるのか。
本当に必要なのか、解決したい課題は何かなどを定義します。

サービスを作るのであれば、そのサービスで実現したい世界など、
why,what の部分を決めておきます。

これが定まっていれば、短期的には今後の開発が大きくぶれることはないと思います。

とは言え、長期的には市場が変化したりユーザーが変化したり、
そもそも自分等の存在意義が変化した時にはここも変わり得るものだと思いますので、一回決めたら絶対変えない!!ということはないです。
むしろ変わることは必然だと想定しておくべきです。

後述しますが、新規にプロダクト(APP、サービス、機能…etc)を作る場合。
それが正しいことが証明できないなら、いきなり莫大なコストをかけて全部作り切るのはやめましょう。

今の時代何が正しいのかわからないので、
最小コストで最大価値が出せるところから細かく市場に出して効果検証を繰り返しましょう。

500万円一気にかけて、ダイヤが出るかただの石ころが出てくるのかというギャンブルをするのではなく、
1万円ずつかけて、時に5千円の価値だったりする時もあるかも知れませんが、価値を検証しながら徐々にコンスタントに1万円以上の価値が出せるようになっていきましょう。

最初からダイヤが出ると分かっている開発ならその限りではないと思います。

要求定義

ここからは個別具体的な機能の話です。
仕様や要件の前に、要求を明らかにしましょう。

課題が特定できたら、誰の何を解決したいのか。
結局何がしたいのかを明らかにします。

例えば、メモアプリなら。
「シェア機能が欲しい!データを出力して受け渡しができるようにしたい!」
の要求は
「チームのドキュメントとして使用したい」
かもしれません。

その場合のHOWは本当にデータ出力で良いでしょうか。
他にもリンクで共有して共同編集機能を作る、どこかにアップロードして共同管理する、gitの仕組みを真似る…など色々とやり方があるはずです。

HOWに詳しいのはエンジニアなので、要求を明らかにしてエンジニアに相談するのが良いでしょう。
(こんな単純な事を間違えるPOはいないと思いますが例なので許してください…)

PO(Product Owner)はWhat,Whyに責任を持ちます。
エンジニアはHOWに責任を持ちます。

要件定義・仕様決め

ざっくりやることは以下

  1. 機能要件の定義
  2. 非機能要件の定義
  3. 計測要件の定義
  4. MVPを意識して適切な大きさにタスクを分解

それぞれ詳しく説明します。順番は決まってないです。

臨機応変に対応してください。
行ったり来たりすることもあります。

機能要件定義

この機能に必要な振る舞いを定義します。
何かの機能を開発する場合、やり方は色々ありますがユースケースを考えると定義しやすいかもしれません。

誰が、何ができればいいのか。を考えます。

例えば、先ほどのメモのドキュメント使用の例だと、

「メモのOwner」が「メモを編集できる」
「メモのOwner」が「メモの権限を編集できる」
「メモのOwner」が「メモを削除できる」
「メモのOwner」が「メモを閲覧できる」
「メモのEditor」が「メモを編集できる」
「メモのEditor」が「メモを閲覧できる」
「メモの閲覧者」が「メモを閲覧できる」

などです。

場合によって文章ではなく表を使うなど、
創意工夫をして伝わりやすく整理された要件を定義しましょう。

要件で齟齬があったり、仕様バグがあると後々の手戻りコストが大きくなってしまいます。

非機能要件

ここは振る舞い意外の、パフォーマンス、セキュリティー、エラーハンドリング、ロギング、モニタリングなどを定義します。

専門的な内容になるのでそれなりの知識が必要です。
振る舞いは正しくても、ここがぼろぼろでは製品として成立しない可能性があります。
同じ機能を持ったアプリでも、なぜか短期間でできたり、安くできたりする場合はこの辺りが犠牲になっていることを疑ってください。

例えば、
100文字程度のメモの表示速度が1時間かかっていたら使えないですね。(パフォーマンス)

「メモの閲覧者」が「メモを閲覧できる」というケースがありましたが、
閲覧者の定義がOwnerが許可した人のみの場合、許可していない人が見れる方法があると困ります。(セキュリティー)

もしユーザーがメモの編集中にサーバーエラーが発生した場合どうしますか?
ただ真っ白な画面だして終わりですか?(エラーハンドリング)
特に検知はしませんか?調査はしませんか?(ロギング・モニタリング)

計測要件定義

非機能要件に入るかもしれませんが、エンジニアのメインの仕事ではないため切り離します。
→ 別途書きます

適切な大きさに分解する

ここだけ異質な感じがしますが結構大切です。
タスクをなるべく小さく、最小の価値のサイズに分解しましょう。

アジャイル開発では MVP Minimum Value Product という言葉がよく使われます。
価値を出せる最小単位のプロダクトのことです。
開発タスクを作る時には常に意識しましょう。

ではなんで大きいままではいけないのか。
理由はいくつかありますが、ざっくり

  1. 一つのブランチで時間をかけすぎるとdevelopとの差分が大きくなる。
    1. 大きすぎると終わらない。
    2. PRのレビューが辛くなる
    3. そのブランチをマージしても大丈夫か確認が必要になる
  2. 価値の検証スピードが落ちる
    1. いかに早く価値を検証するかが大切なのに、
    2. 取り組んでいた時間は何も価値を出していないし回収できない。
    3. その間に市場が変わってしまっているかも知れない
  3. 見積もり精度が下がり、開発計画に支障が出る
    1.  タスクの単位が大きいと、色々な問題が絡みあって見積もりが難しくなる
    2.  そもそも見積もりに時間がかかる
    3.  細部まで考えきれず、着手してから問題が見つかることも

開発の計画

要件が決まったら、開発の計画を立てます。

優先順位決め

まず何を優先して着手するのかを決めます。
優先度ではなく優先順位です。全部優先度高とか言われても困るので…
どれから着手するかを明らかにしておきましょう。

リリース計画

リリース日、リリースサイクル決めましょう。
その際、先ほど決めた順位の中からどこまでを1stで必須でだすのか、それ以降のリリースで順次でもいいのかの線引きをしましょう。
ここでも当然MVPを意識してください。ビジネス的な観点でそれだけ出しても勝てない使えないなどの判断もあると思いますので、うまく調整しましょう。

SQCD

開発計画を立てる際にはをSQCD意識しましょう。

開発計画にはSQCDという考えがあります。
「S:スコープ、Q:クオリティ、C:コスト、D:デリバリー」のうち何が変更できないのか、何を許容できるのかを見定めて計画を立てる必要があります。

例えば。
D:デリバリー(期日、リリース日)とC:コスト(開発者数)が決まっている場合、
S:スコープ(どの機能まで実装するのか)、Q:クオリティー(品質、どの程度のバグを許容するのかなど)をコントロールして間に合わせたりします。

開発の設計

どうやって要件を満たすのか、HOWを決める
パフォーマンス、セキュリティなどもHOWの検討材料になります。
インフラ、使用技術、アーキテクチャなどの設計を検討しましょう。

テスト設計

ここも細かい話になるので、詳細は別で書こうと思います。

テスト設計ではどんな品質を担保したいのかを設計する。
テスト=振る舞を担保するものです。
これが正しく動きますよを担保しているだけで、想定外のバグは見つけられません。

テストには

  • 手動テスト
    • 機能ごとのテスト
    • 機能間テスト
    • シナリオテスト
    • モンキーテスト
    • スモークテスト
  • 自動テスト
    • UI テスト styleとか
    • Unitテスト 単一機能
    • integrationTest 統合機能
    • e2eテスト end to end test

など色々あります。
ここでは共通する概念を紹介します。

ざっくり3パターン

正常系: 期待している正常な動作が担保できているか
準正常系: 想定しているが正しくない動きに対処できているか
異常系: 想定外の動きの対処ができているか

例を示します。

ex 名前入力フォーム 姓、名(日本語)

正常系

given 前提条件
	他が入力済み

when 手順(何をした時)
	姓:山田
	名:太郎

then 結果(どうなる)
	OK→「山田太郎」と表示される。

準正常系

given 前提条件
	他が入力済み

when 手順(何をした時)
	姓:48623
	名:👀

then 結果(どうなる)
	「姓名は数字や特殊文字は使用できません」と表示される。

異常系

given 前提条件
	他が入力済み

when 手順(何をした時)
	「姓:テスト、名:太郎」が同時に二重に登録される。

then 結果(どうなる)
	サーバーエラー
	→時間を置いてアクセスしなおしてくださいと表示される

余談ですが
自分は、テスト書かないor軽視しているエンジニアとは仕事したくないと思っています。
初心者だからかけない、ということはないです。

最初の設定が面倒なだけです。
(テスト軽視する文化でエンジニアになったつもりになるのは危険だと思っています)

これも詳しく言うと色々あるのでドキュメントどこかに残しますね…

開発

実際に開発する

自動テストやリントを使い、開発時に発見できるバグは潰しておく。

コードを書く時は可用性、拡張性など考慮↓ここに記載しています。
AIESEC-in-Japan/aiesecjp-web

検証・テスト

本番同様に非公開の環境で動作を検証する。
担保したい機能が担保できているのか、エラーが発生しないかなど
事前に行ったテスト設計に従い、テストを実行する

余談:検証で使っているもの

  • netlify
  • cloudflare page(うまく設定できていない)

PRごとにプレビューを作ってくれるので活用しています。
ただ、cloudflareの方が決算の関係でうまくできていないので、一時的にnetlifyを使用しています。

リリース

テストもレビューも問題なければリリースを行い、本番に変更を適応する。
リリース前テストとして、全機能のうち壊れていたらリリースできない機能のテストを行う。

リリース手順

git flowに従い

release/{date}
ex release/2021-07-01

のようなブランチを作成しmasterに向けてPRを作成し、以下を確認したのちマージしてデプロイ。

  • 変更内容に余計なものが入っていないか、意図しない変更が入っていないか
  • CIが正常に終了するか
  • 複数機能複数モジュールに跨がる統合的なテストを実施

余談:リリースに使用している技術

  • cloudflare page
  • cloudflare DNS
  • cloudflare SSL/TSL
  • cloudflare GateWay
  • cloudflare fireWall

以前は自前でサーバーを用意して、LAMPの構成でどうにかデプロイしていましたが
もっと簡単にできるのでcloudflareに全て寄せました。

公開

本番適応したら公開されます。
しばらくはエラーがないかの確認と、できるなら本番環境を確認して変更が適応されているか確認しましょう。

効果検証

何かをリリースして終わりではなく、どの程度のユーザーがきているのか、期待通りに使ってくれているのかなどの検証を行います

余談:現在適応されているのは

  • cloudflare analytics

ここもちゃんとやりたい…
何をすべきかなどちゃんとドキュメントとして残しておきますね。

分析と改修→1に戻る

検証データの分析結果と、全体の方向性に基づいて次の開発目標を定めます。

Discussion