現場で使えるソフトウェアテスト

[現場で使えるソフトウェアテスト Java編](http://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%83%86%E3%82%B9%E3%83%88-Java%E7%B7%A8-%E9%A3%AF%E5%B1%B1-%E6%95%99%E5%8F%B2/dp/4798114634)を読んだので要点をまとめ。

#Step1 テストとは
ソフトウェア開発では、様々な問題が発生するが、そのなかでよくあるのが`動かない`、`誤動作`、`パフォーマンス問題`人が作る上でミスは起こるのでテストが必要

```
網羅的検証（ソフトウェアテスト） ＝ 利用時に問題が起こらない品質を確保するためにバグを見つける活動
```

##テストの流れ

1. 品質目標を立てる
テスト密度（目標、上限、下限値）、バク密度（目標、上限、下限値）

1. テスト計画
ソフトウェアテストの全体計画作成
実施スケジュール、予算、体制、環境構築手順、必要ツール利用手順、成果物の様式、バージョン管理、設計書の準備
1. テスト作成
期待動作、パターンの洗い出し、テスト環境構築、テストデータの作成、テストケース作成、レビュー
1. テスト実施
作成したテストケースの実行
1. テスト検証
結果の確認、テスト関係者以外の利害関係者との調整（設計書管理、仕様管理、修正管理）、テスト実施者の作業管理、テスト報告のとりまとめ、テスト全体報告、再テスト有無判断
1. 再テスト
検証で再テストを判断したケースの再テスト
1. 品質評価、判断
・品質管理者（テストが要求品質を達成できているか判断）
・テスト管理者（主に開発リーダーなどのテストなどにおける経験によりテストの実施、人員のとりまめ）
・テスト実施者 → 小規模プロジェクトでは各役割を兼任することもある。また開発者がテストの関係者に移行する場合もある。





#Step2 テスト前のバグ予防策
単体テスト工程でバグ発見は可能だが、そもそもバグ自体を予防することで開発をよりスムーズに進めることが出来る

## 静的解析ツールとソースレビューによるバグ予防手順

1. コーディング規約作成
言語特有のコーディング作法、プロジェクトごとのルール（変数、メソッドの命名規則）、要件定義で指定された業務ロジックとの整合性

1. 品質レベルの定義
保守性、作法のレベル定義の明確化
読みやすさの定義
ルール数は適度に → 多くしすぎるとプログラマーが把握しきれない
※Javaコーディング規約2004などをたたき台にするとよい
1. 静的解析ツール選択、設定
__静的解析を行うことで、レビュー時の確認内容が削減できる__(コーディング規約にそうように静的解析ツールの設定を行う)
予算と機能のバランスを考え選択
低品質なソースに関してソースレビューは非効率なため、予め静的ツールの指摘率（指摘数÷ソースコード行数）を決めてく
静的ツールにあえてエラーになるような記述をする場合には、それをリスト化するとレビューがスムーズになる
1. レビュー観点の作成
*目的*
・ソースコードの品質均一化
・ソースコードの保守性向上
・開発チームへのノウハウ横展開
・修正コストの削減
レビュー時にレビューアーの認識に差異ができないように事前に作成する
コーディング規約から抽出 → 静的解析ツールでチェックできないものなど
仕様から抽出 → 外部インターフェイスの呼び出し方のマナー、業務ロジックなど目視でなければ確認できないようなプログラミング方法、アルゴリズムや設計に関連する問題など
1. プログラミング
事前にプログラマーにコーディング規約とレビュー観点を徹底して説明 → 認識に違いがあるとレビュー、修正などの余計な時間が発生する
フォーマッタは必須
1. レビュー実施
事前に静的解析を完了したソースに対し、レビュー観点に沿ったレビューを行う
QCDのバランスを考慮したレビューが重要。具体的には下記のような感じ
・プログラマーごとに最低１つのソースコード
・アプリケーションが提供する機能別に、そのて機能の中心となるソースコード
・プロジェクトとして初めて提供する機能のソースコード
・プロジェクトメンバーが難易度が高いと指定したソースコード
全てのプログラマレベルは均一ではないため、必ず全員をレビューする。また難易度を面からレビュー対象を選定すると効率的
レビュー観点としては、クラスの仕様、設計、アルゴリズム、コメント記述など
1. ソースコードレビューの評価：レビューの指摘で上がった問題を分析する
評価する観点
・バグの種類（メモリーリーク、デッドロック等）
・バグの傾向（クラス、ファイル、メソッド、プログラマ等）
・バグの原因（設計ミス、プログラムミス等）
上記を確認し、今後同じような指摘が発生しないように対策を検討 → メンバーにフィードバックを行う

*静的解析ツール、コードレビュー重要!!*


###ソースコードレビューの必要性

> 平均的バグ検出率は30%、その後のテスト35%。複数人によりソースコードレビュー実施時のバグ検出率は60%。（Code Complete 第2版）






#Step3 テストコードの作成
ここに記載する内容を理解し、手順に従いテストコードの作成を行う
## 品質の高いソフトウェア
作るには、`要求をプログラムレベルまで把握`、`要求がプログラミングできているか厳密にテスト`の2点が必要

* テストコードのプログラミング
テスティングフレームワークを使用することで、開発効率、品質、開発容易性、統一性、メンテナンス性などの向上が望める
→ 要はメジャーなフレームワークは品質も情報量も開発メンバーの経験値も高いのでメリットが多い

* 単体テスト
事前に「目的」「作業範囲」を決めておくことが重要
限られた期間、予算内で単体テストを行うにはメソッドの処理パターンを分析し、網羅性を確保し、重複を省いたコード作成が必要
「テスト実行前状態」「テスト実行後状態」を考慮した単体テストを作る（例えば、入力値による分岐だけでなく、処理中に行うDBの値によって変化するようなものは、DBの状態も複数作成する）
* ブラックボックステスト
・同値分割法
分岐処理などで、各分岐内に定量的なデータを使用する
・境界値分析
同値分割後、分岐内の境界を分析し使用データを
* ホワイトボックステスト
コードガバレッジを把握する
・命令網羅
コード内の全ての命令を1回以上実行すると100%
・分岐網羅
分岐に対して、真偽を1回実行すると100%
・条件網羅
条件に対して、全ての値を1回実行すると100%
・複合条件網羅
テスト内の分岐全ての組み合わせを1回以上実行すると100%

命令網羅や分岐網羅、複合条件網羅が100%でも品質が確保されているとは限らない
→ 例外処理や仕様理解不足など考慮しきれな場合はあるのであくまでもカバレッジは指標として使用する

* Webアプリケーションのテスト
Webアプリケーションなど、サーバ、HTTP通信などの複雑なクラスが存在するため、それらをサポートするツール、ライブラリなどを利用し、クラス間の関係を極力省いたテストを行う
→[Javaのユニットテスト・ライブラリ・ツールまとめ](http://qiita.com/disc99/items/808a57e8de41fe75a5dd)

##テストケース作成手順

1. 仕様理解
メソッド仕様を理解し入出力のパターン、関係を分析

1. テストケース抽出（仕様観点）
仕様からテスト処理の粒度、テストケースの量を把握
1. プログラム構造理解
メソッドの分岐、繰り返し、例外などの把握
1. テストケース抽出（プログラム構造観点）
プログラム構造も考慮したテストケースの把握
1. 省略できるテストケースの分析
ここまでの作業で抽出した情報をもとに省略できるケースの判断
1. 実行するテストケース数の決定
今までの情報をもとに、プロジェクトのQCDを考慮したテストケースの決定
1. テストシナリオ作成
どういった仕様をテストするためのテストケースか？、実行するためにどんな入力値、実行前状態が必要か？、実行後出力、テスト後状態がどうなるか？なども考慮する
1. テストデータ決定
効率の高いテストデータを利用する


## テストコード規約を作成する
テストコード規約を疎かにすると、保守性が低下し、仕様変更時などにテストコードを修正する手間がかかるので必ず作成する
###よく使われるテストコードの構成

```
パッケージ構成
　テストクラスと同一パッケージ
　※フォルダを別にし、フォルダをソース側は「main」、テストコード側は「test」
クラス名
　「テスト対象クラス + Test」
メソッド名
　「test + テスト対象メソッド名 + 連番」
テストメソッド宣言で必ず「throws Exception」を使用する
1つのテストメソッドでえは１つのテスケースだけをプログラミングする
```

#### テストコードを作成する
テストの前後処理はsetUp、tearDown（JUnit4以降なら、@Before、@Afterアノテーション）メソッドを使用する（ネットワーク接続/切断、DB初期化、外部ファイル初期化）
テストクラス内で一回だけ実行するなら、@BeforeClass、@AfterClassを使用する


## テストコードレビューをする
*レビューの注意点*

* プログラマごとに最低１つのテストコードを必ずレビューする
* 機能別に、中心となるソースコードのテストコードは必ずレビューする
* プロジェクトとして初めて提供する機能を実現するソースのテストコードは必ずれびゅーする
* 難易度の高いソースのテストコードレビューは必ずする
レビュー観点
* 規約が守られていること
* 事前状態、引数、検証内容がテストケースの内容と一致していること
* 処理ロジックに誤りがないこと
* 前処理、後処理が適切に記述されていること
* 実行順序によって結果が変わるような記述になっていないこと
* テスト内容を表すコメントが適度に記述されていること
* スタブ、ドライバが正しく利用されていること



#Step4 効率的な単体テスト
作成したテスト内容やテストコードを実行するだけではなく、ここで示すことに注意してテストを行う

##単体テストの実行
テスティングフレームワークを使用しテスト実施

* テスト環境の統一
OS、ミドルウェア、外部リソース（ファイルなど）、クラス変数、DB（テーブル内の値）
→ VMなどを利用するプロジェクトも増えている
機能テストと非機能テストは分けて行う
→ 環境やツールを変更しなければならないことも多いので、作業効率が悪い
非機能テストの記録も行う

* テスト結果確認
実行結果と期待値の比較、その他レスポンス、リソースの増加などの観点にも注意

##テスト結果記録
所定のフォーマットで記録する
###記録を行う項目
* 作成日付

* 記録した人
* テスト環境
* テスト対象のソースコードを一意に識別できる情報
* 予想どおりの結果を返さなかったテストコードのクラス・メソッド名
* 再現方法
* 結果
* 重要度
* 現在の対応状況
→ *バグ管理ツールを使うのが最適*

###バグの解析、修正（デバッグ）
起こる故障原因リスト

* 設計書記述ミス

* ソースコードミス
* テストケースミス
* テスト環境ミス
* テスト実施ミス
* その他、ツールやライブラリ自体にバグがあるなどのミス
 → バグの原因により対処方法を検討する

##テストコードの修正
修正内容の量を把握し再テストまでの予定を建てて修正を行う
→ 完了後、再テスト：テスティングフレームワークを使用することで回帰テストの効率化が図れる





#Step5 ソフトウェアの品質評価
単体テスト実施結果をもとに、作成したソースコードが期待どおりの品質か確認する
###なぜ
テストの妥当性、バグの出しきり確認
→ 取りまとめて品質評価が必要
###誰
メインは開発リーダー、品質管理者。ただし、プログラマも自分の担当分に関しては責任を持つ
###いつ
全てのクラステスト完了後では手遅れになる可能性があるので以下のタイミングで行う

* プログラマ
1クラスのプログラミング、単体テスト完了後

* 開発リーダー、品質管理者：定期的（できれば毎日）
→ バグが発生しても早期発見、対策が可能

##品質評価の作業手順

1. 品質評価データ取得
1. 品質評価データ分析、品質評価の実施
1. 問題箇所の見直し/修正
1. 品質報告書の作成

##QC7つ道具

* 特性要因図
特性（結果）と要因との関係を表す、通称「魚の骨」。開発において発生した問題の原因を洗い出すときに使用

* パレート図
現象、原因など項目件数を大きい順に並べた棒グラフとその追跡わの折れ線グラフを重ねて表す。
バグの原因で使用すると、上位のバグ原因がどのくらいの割合かわかる
* ヒストグラム
データ範囲を区間分けし、各区間の出現頻度を棒グラフ化。データの分布、形、中心位置、バラつきを把握できる
* 散布図
2項目を縦横軸にとり、分布状況をプロット。バラつきから2項目間の相関関係有無を確認
* チェックシート
項目表でチェック漏れを防止。ソースコードレビューなどで使用
* 層別
データの特徴ごとにグループ分け。ソースの特性ごとに層別を行い、品質評価基準をグループ化する
* 管理図
データ変動の折れ線グラグと、その上下限の管理限界線を明示。管理限界線を超えると異常な状態を示す

##品質評価の技法
###定量評価（メトリクス）
テストにおいて十分のバグを出しきったことを評価する

* テスト密度
テスト対象のソースコード用数に対して順分にテストケースを実施しているか

```
テスト密度 = テストケース数 ÷ ソースコード行数
```

* コーガバレッジ
テスト対象の構造に対して、十分なテストが実施されてるか

```
命令網羅 = テストで実行した命令文数 ÷ 全命令文数
分岐網羅 = テストで実行した分岐数 ÷ 全分岐数
```

* 未修正バグ
修正していないバグが残っていないか
`検出されたバグのうち修正されていいないものの数`
* バグ密度
テスト対象のソースコード行数にたいして十分なバグを検出しているか

```
バグ密度 = 検出バグ数 ÷ ソースコード数
```

###その他メトリクス

* サイクロマチック数
if、switchなどの制御パス数をカウントし処理ロジックの複雑性を判断。「バグの作りこまれやすさ」、「テストのしづらさ」などが分かる

* ネストの深さ
ネストの深さを計測し、ソースの可読性、バグの作りこまれやすさを判断
* 凝集度
クラス、メソッド間の結びつくを判断。凝集度が低い場合、別クラス化を検討
* 結合度
依存関係のあるクラス数をカウント。結合度が低いほど、クラスの独立性が高く、修正コストが低いことを表す

##メトリクスを利用した評価の方法
どのくらいの値ならOK、NGを事前に決めておく（目標値と、その上限値、下限値）
→ 過去のプロジェクトなどを参考にする
また、メトリクスの組み合わせも可能で、例えばテスト密度が高く、バグ密度が低いと、テストを実施し過ぎたのに網羅性が低いなど、それぞれの状況に合わせ判断ができる

##時系列データにより品質評価（バグ収束曲線）
テスト実施日の時間軸と、累計バグ数の折れ線グラフでバグの収束予測、また予測に対する差異による問題点を判断する

##定性評価
メトリクスを利用した、品質評価は、`数字では測れない部分`、`測定対象データの誤り`などが含まれる可能性があるため、全ての品質評価、ソースコード、テストケース、バグ情報をもとに、定性的な品質評価を行う
方法としては、テストケースのバグの内容をグラフや表化して判断
例えば、仕様、プログラミング、テストミスとその内容（期待値の相違、例外発生、性能劣化、トランザクションエラー）ごとに表化し、ミス内容ごとにグラフ化する


#おわりに
ここでまとめたことは全てではないので、プロジェクトや現場に合わせて必要な部分を変更しながらベストなテストを！