真面目にシステムの品質を設計し、作り込む手順を考える

# 位置づけ

本当に完全に全くの0から中規模以上のシステムを作る場合の知見をまとめます。
また、開発フローもアジャイル・ウォーターフォールをあまり気にしていません。
多分どちらでも使えると思います。
残念ながらインフラ領域は門外なので、割愛します。

# 参考
IPA非機能要求グレード
https://www.ipa.go.jp/sec/softwareengineering/std/ent03-b.html
Webシステム／Webアプリケーションセキュリティ要件書 3.0
https://github.com/ueno1000/secreq
モバイルアプリケーションセキュリティ検証標準
https://github.com/coky-t/owasp-masvs-ja
git-flow
https://nvie.com/posts/a-successful-git-branching-model/
github-flow
http://scottchacon.com/2011/08/31/github-flow.html
https://gist.github.com/Gab-km/3705015
gitlab-flow
https://postd.cc/gitlab-flow/


# 想定する開発フロー

やりたいこと、その規模（XX月後、XX年後にこのくらいの売上になっていたい）が定義された状態で
非機能とかインフラ選定・技術選定しようとする段階をターゲットにします。

<img width="632" alt="スクリーンショット 2019-12-05 17.28.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84539/fd746c58-b39e-81c1-e4ab-38de3fecf2d2.png">


# ドキュメントフロー

フォーマットなどは特に気にしたいのですが、 `決める必要がある` といった観点で以下のフローを想定します。
これもあくまで目安程度です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84539/a1df29e8-1df6-0e14-92d2-fed943097e02.png)

# 品質設計の手順

## 1.非機能要求を元にした要件定義

IPAの非機能要求グレードの活用表をもとに、今から作るシステム特性を検討し、非機能要件を決めます。
IaaS（AWS..etc）、PaaS(Heroku)などでも十分有効に使えます。
https://www.ipa.go.jp/sec/softwareengineering/std/ent03-b.html

### 利用方法

一般論レベルですが、結局

* 06_活用シート.xls

を全部上から下まで舐めるだと思います。
ただし、誰が決めるかは要求のセクションによって担当を分けるべきだと思います。


### 樹形図を見て担当を決める

Bの章が「システムを実装する」観点では重要になります。
重要項目とされていませんが、この段階で性能テストもある程度考えておくと実装後に慌てるタイミングが減ります。

<img width="2145" alt="スクリーンショット 2019-12-05 18.27.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84539/c5d2255c-d6a2-744f-b14f-ebb6aef4afd9.png">

また、Eの章ではセキュリティも定められているため（実装観点ではセキュアコーディングしましょうといったレベルですが）確認が必要です。

<img width="2085" alt="スクリーンショット 2019-12-05 19.09.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84539/7db2ab87-382f-8685-6b51-4dbff93c4d22.png">


## 2.セキュリティ要件を決める

実装方式に影響するため、設計・実装よりも前に確実に詰めます。

### サーバサイド・バッチ

OWASPの「Webシステム／Webアプリケーションセキュリティ要件書 3.0」がとてもわかり易く要件を整理していえるため、
こちらをもとに要件を検討すると決めやすくなります
https://github.com/ueno1000/secreq

### モバイル・SPA

OWASPの「モバイルアプリケーションセキュリティ検証標準」がとてもわかり易く要件を整理していえるため、
こちらをもとに要件を検討すると決めやすくなります
https://github.com/coky-t/owasp-masvs-ja

## 3. 実装計画

### ブランチ設計

バージョン管理として、Gitを前提に検討します。
開発を始める前にブランチ運用を決めることはとても重要です。
この運用を決めないと、CI/CDも構築できません。

事実上デファクトになっている運用flowがあるので、想定する開発の回し方に応じて選択・カスタマイズが必要になります。

#### git-flow

flowは本当によくできており、高い理想を感じるのですが、実際の開発現場でこれを完全に回しきった事例をあまり見ません。
<img width="608" alt="スクリーンショット 2019-12-05 20.11.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84539/9203e066-08b9-6406-b947-71595d279407.png">

#### github-flow

本番環境＝masterのとてもシンプルな構成です。
単純すぎてこれで本当にこれで運用が回せるのか不安をいだきます。
hotfixなどの考えを入れて運用するパターンが多かったです。
<img width="796" alt="スクリーンショット 2019-12-05 20.43.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84539/5d2dd73f-f346-bf0f-34fd-a0cc449a7a64.png">

#### gitlab-flow

(ちょっと違いますが)github-flowに環境面の考えを入れたflowです。
現実に落としてきた感じがします。
<img width="587" alt="スクリーンショット 2019-12-05 20.48.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84539/87c7a6a5-905a-73a0-52c2-bd46fe888dc0.png">


### 規約

いわゆるコーディング規約です。
フォーマットレベルの話はlinterに任せるべきですが、それ以外（命名・変数の使い方など）は全体の品質を平準化させるために必要だと思います。

### linter

言語・フレームワークに合わせて有効なLinterを選定し、ルールは規約に合わせて書き換えましょう。

### CI(CDは割愛)

できればgitpushに引っ掛けて段階でCIでできる限りのチェックを実行したいです。
品質担保・レビュワーの負荷軽減のためです。

- literチェック
- 静的バグ解析（linterに含まれる場合もあり）
- UT
- e2e

### ペアプロ

経験の浅い人のコードはどうしてもお作法も、ロジックもベテランに比べて品質が低くなります。
そこで始めの1本はペアを組ませて書き方を学んでもらいましょう。

### レビュー

github/gitlabの機能が充実しているので、全面的にPullRequest/MergeRequestのレビュー機能を利用すると良いです。

## 4.テスト計画

設計・実装の前にテストの定義をすることで、以下の様な実装段階で発生する問題が事前に検討・解決できます。

* テスト内容のばらつき
* テストのやり過ぎ
* テストの不足
* あれ？このテスト何をやったら終わるんだ？といった疑問

増減はしますが、私の理解の範囲では以下のようなテストが一般的に実施されると思います。
また、セオリーとしてテスト範囲は最小粒度から徐々に広くしていきます。

<img width="895" alt="スクリーンショット 2019-12-05 21.35.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84539/cd6fb468-a5fa-62e8-0419-4d53664ad314.png">

1. UT<br>
ホワイトボックステスト - いわゆるテストクラスの範囲<br>
基本はカバレッジを保証するもので、この保証のレベルを定義します<br>
一般的に以下のキーワードで調べると指標がわかりやすく解説されています<br>
C0/C1/C2/MMC<br>
**重要なのは「C0を選択した場合もMMC相当の保証を後続のテストでは実施する必要がある」という点です。**
2. e2e<br>
End to Endの略です<br>
ブラックボックステスト - apiであればRequest/Response、画面であれば画面の挙動確認（Selenium他）をするものです。<br>
機能単位のインターフェイス（データパターン）を保証するテストになります。<br>
**テストクラスをサボるとここが厚くなります。**
3. 特定サービスのテスト<br>
個別の機能が保証された前提で、サービスが正常に動作するかを確認するテストになります。
4. 自ステムのテスト（機能）<br>
サービスが保証された前提でシステム全体を確認するテストになります。
5. 自ステムのテスト（非機能）<br>
非機能で定義した要件を満たしているの確認するテストになります。<br>
アプリケーションとしては、性能試験、セキュリティ試験がここに当てはまります。
6. 外部システムとの結合テスト<br>
例えば別会社のシステムからRequestを受け付ける、ファイルを受け取るなどの処理から、システム全体としてビジネスを実現できるのかを確認するテストになります。


# 最後に

ここまでを100％設計前に実施するのは、大体の場合期間の制約で不可能です。
ですが、検討した上で落とすのと、最初から通すのでは品質に雲泥の差がでるので、リスク踏まえて落とす・落とさないの選択が必要だと思います。