# テスト

## テスト自動化

1. 手動テストはなくならない
2. 手動でおこなって効果のないテストを自動化しても無駄である
3. 自動テストは書いたことしかテストしない
4. テスト自動化の効用はコスト削減だけではない
5. 自動テストシステムの開発は継続的におこなうものである
6. 自動化検討はプロジェクト初期から
7. 自動テストで新種のバグが見つかることは稀である
8. テスト結果分析という新たなタスクが生まれる

[https://sites.google.com/site/testautomationresearch/test\_automation\_principle](https://sites.google.com/site/testautomationresearch/test_automation_principle)

## テスト文書一式

| 分類  | 成果物     |
| --- | ------- |
| 計画書 | 試験計画書   |
| 計画書 | 試験計画書   |
| 試験  | 試験手順書   |
| 試験  | 障害処理票   |
| 成績書 | 試験成績書   |
| 成績書 | エビデンス   |
| 成績書 | 試験完了報告書 |
| 成績書 | 品質報告書   |

## テストの種類

| テスト名                                           | 概要                                                                    |
| ---------------------------------------------- | --------------------------------------------------------------------- |
| タスク指向機能テスト（TOFT：Task-Oriented Functional Test） | アプリケーションの各機能が実行するタスクが、仕様書・ユーザーガイド・要求仕様書・設計文書に違反する動作をしていないかを確認する正常系テスト |
| タスク指向機能テスト（TOFT：Task-Oriented Functional Test） | アプリケーションの各機能が実行するタスクが、仕様書・ユーザーガイド・要求仕様書・設計文書に違反する動作をしていないかを確認する正常系テスト |
| 強制エラーテスト（FET：Force-Error Test）                 | プログラムを強制的にエラーにするよう設計された異常系テスト                                         |
| 境界値テスト                                         | 極端な入力データに対するプログラムの応答を確認する                                             |
| システムレベルテスト                                     | システム全体を通して動作させ、正常に機能するかを確認する                                          |
| 現実のユーザーレベルテスト                                  | ユーザーがプログラムに対して行うであろうことを予測してテストする                                      |
| 探索型テスト                                         | 問題の「起こりそうな」場所に焦点をしぼってテストする                                            |
| 負荷／ボリュームテスト                                    | プログラムが大量のデータ／計算／処理をどのように扱うかをテストする                                     |
| ストレステスト                                        | 限られたリソースのもとでプログラムを動作させる                                               |
| パフォーマンステスト                                     | ユーザーが許容できるシステム性能を維持するための効果的な方法を作成するために行う                              |
| フェイルオーバーテスト                                    | システムレベルのエラー処理やリカバリプロセスをテストする                                          |
| アベイラビリティテスト                                    | システムやコンポーネントが動作可能でアクセス可能な状態となるまでをテストする                                |
| 信頼性テスト                                         | システムが一定時間の間連続で操作可能かをテストする                                             |
| スケーラビリティテスト                                    | システムの拡張性をテストする                                                        |
| APIテスト                                         | ハーネスアプリケーション等を利用し、APIをテストする                                           |
| 回帰テスト                                          | バグ修正後に、それが確実に修正されているかと、新たなバグが発生していないかをテストする                           |
| 互換性テスト、構成テスト                                   | アプリケーションがさまざまなハードウェアやソフトウェア上で正常に機能するかをテストする                           |
| ドキュメントテスト                                      | リファレンスガイドやユーザガイドが正しく記述されているかをテストする                                    |
| オンラインヘルプテスト                                    | オンラインヘルプの内容やヘルプシステムが正常に機能するかをテストするユーティリティ、ツール、その他付属品のテスト              |
| システムに付属するもののテストインストール／アンインストールテスト              | インストーラのテスト、READMEやアイコンの確認、インストールした機能が正常に動作するかをテストする                   |
| ユーザーインタフェーステスト                                 | 使いやすさや見た目の評価、UIが仕様通りに動作するかをテストする                                      |
| ユーザビリティテスト                                     | 使いやすさやユーザーの満足度をはかる情報を収集するなど                                           |
| 外部ベータテスト                                       | プログラムを試しフィードバックをくれる外部の協力者にテストしてもらう                                    |
| 日付テスト                                          | 2000年問題や2038年問題のテスト                                                   |
| セキュリティテスト                                      | 脆弱性／情報洩れなどがないかをテストする                                                  |
| 単体テスト                                          | ソフトウェアをほかのソフトウェアと結合する前に単体でその完全性を評価する                                  |

## 特性

* 操作性（実行性）
  * 自動テストのプログラムから対象のプログラムを実行し、制御できること
* 確認性
  * 対象のプログラムを実行した結果が正確に確認できること
* 再現性
  * テストを行う特定の状況を再現できるこ
* 理解性
  * テストスクリプトが読みやすく理解しやすいこと
  * テストスクリプトを容易に作成することができること
  * テストスクリプトができるだけ多くのメンバーが作成できること
* 効率性
  * 多様で効果的なテストスクリプトを適切なコストで作成できること
  * 必要な自動テストを効率的に運用することができること
* 保守性
  * テストスクリプトはテスト対象の変更に素早く対応する必要がある
  * テストスクリプトの変更が容易であること
* 拡張性
  * テストスクリプトの機能を必要に応じて拡張できること
* 安定性
  * テストスクリプトを安定して実行できること
  * 同じテストスクリプトを何度でも安定して実行できること
* 信頼性
  * テスト結果の判定が信頼できること
* 移植性
  * 異なった環境でテストを実行できること
* 柔軟性
  * 状況に合わせて、柔軟な運用ができること
* 障害許容性
  * 対象のプログラムで予測しないエラーが発生しても、他のテストス クリプトが継続的に実行できること
* 並列性
  * 複数の環境で効率的にテストを並列して実行できること&#x20;

## テスト技法

| テスト名                   | 説明                                                                      |
| ---------------------- | ----------------------------------------------------------------------- |
| アドホックテスト               | 直感や経験に基づくテスト設計・実行する手法                                                   |
| 探索的テスト                 | テストの設計と実行を同時に平行して進める手法                                                  |
| 同値分割                   | 同じ結果をもたらす集合（同値クラス）に分割し、各集合の代表値を用いてテストを行う手法                              |
| 境界値分析                  | 同値クラスの境界値付近（境界値、境界値の前後）を重点的にテストする手法                                     |
| ドメイン分析テスト              | 同値分割と境界値分析を多次元に拡張した手法                                                   |
| デシジョンテーブル              | 入力条件の全ケースと出力との関係を表形式で整理する手法                                             |
| 原因ー結果グラフ               | 入力条件や環境条件などの原因と、出力などの結果の論理的な関係をグラフで表し、最終的にデシジョンテーブルに展開することでテスト項目を設計する手法 |
| FD(Cause Flow Diagram) | 原因結果グラフの発展形ともいうべき技法で、同値分割、デシジョンテーブルの手法を組み合わせた手法                         |
| 状態遷移テスト                | 状態遷移を状態遷移図や状態遷移表を使ってテストする手法                                             |
| ランダムテスト                | テストの入力値にツール等でランダムに生成した値を使ってテストする手法                                      |
| ペア構成テスト                | パラメータや環境の組合せテストにおいて、組合せの爆発を避け、バグ摘出効果の高い組合せ（2因子のペア）を重点的にテストする技法          |
| ユースケーステスト              | ユースケース(\*)記述を元にテストする手法                                                  |
| トランザクションフローテスト         | トランザクションフローグラフを用いてトランザクションをテストする技法。                                     |
| 制御フローテスト               | ソースコード内のパスを網羅する観点で行われるテスト。複数の網羅基準がある                                    |
| データフローテスト              | プログラム内の変数に注目してテストする手法                                                   |
| 静的解析                   | プログラムを実行することなしに、与えられたプログラムのコードを解析して、プログラムの実行時の属性を発見する解析手法               |
| エラー推測                  | 対象プログラムにおいてありがちなエラーを想定し、テストケースを設計する手法                                   |
| 運用プロフィール               | 運用時に利用される状況をできるだけ忠実に再現するテストをする際に用いられる手法                                 |
| アプリケーションの性質に基づいた技法     | テストされるアプリケーションの性質に特化したテスト技法                                             |
| リスクベーステスト              | リスクの高い箇所からテストを優先的に行う手法                                                  |
|                        |                                                                         |

## テスト項目

| テスト項目番号 | 確認内容 | 操作手順 | 確認結果 | 確認日 | 確認者 | 障害報告票番号 |
| ------- | ---- | ---- | ---- | --- | --- | ------- |
|         |      |      |      |     |     |         |
|         |      |      |      |     |     |         |

1. 顧客の視点で記述する
2. 「正常系」テストと「異常系」テストの区分を明示する
3. 操作手順は簡潔に書く

※結果は、OK,NGでなく問題なし、問題ありで記述すること

## テスト計画書（試験計画書）

* スケジュール
* 体制
* テスト目的・範囲
* テスト定義
* テスト環境
* テストの粒度
* 進捗管理指標
* 不具合管理
* 構成管理

日経BP社 体系的ソフトウェアテスト P349から抜粋

1. テスト計画書識別番号
2. 目次
3. 参考資料
4. 用語集
5. 概要
6. テスト項目
7. ソフトウェアのリスクに関する問題
8. テスト対象機能
9. テスト非対象機能
10. アプローチ
11. テスト項目の合否基準
12. 一時定期基準と再開要件
13. テスト資料
14. テストタスク
15. 環境条件
16. 責任
17. スタッフの配置とトレーニング
18. スケジュール
19. プランニングリスクと対応策
20. 承認

## テスト仕様書（試験仕様書）

### 目的

* システムの振舞いを外部からチェックする手順を定めた仕様書。”動作確認”という曖昧な作業の内容を可能な限り明確にし、迅速かつ確実なテストを実行できるようにすることが、この仕様書の目的。
* システムがきちんと完成していることが簡単に確認できる文書
* 求める機能や性能が要求どおりの品質になっていること
* 業務作業に支障ない使い勝手やユーザーインターフェイスになっていること
* システムを導入するメリット（業務効率の改善、導入前より業務作業がやりやすくなるなど）が達成されていること

### 項目

1. テストを実施した環境
2. 実施するテストの内容
3. テストを実施するためのシステムの操作手順
4. テストの実行結果
5. 個々のテスト項目を識別するための番号や記号（通し番号など）
6. テストを実施した年月日
7. テストを実行した担当者
8. 障害報告票番号（発生した障害の詳細を開発グループに報告する帳票の識別番号）

[http://www.atmarkit.co.jp/ait/articles/1008/25/news106.html](http://www.atmarkit.co.jp/ait/articles/1008/25/news106.html)

### 内容

**大枠レベル**

* 試験区分
* 試験実施方針

**各項目レベル**

* 試験概要
* 前提条件
* 試験対象
* 試験実施者
* 試験実施環境
* 試験コンフィギュレーション
* 試験データ
* 試験手順（試験項目、記録と保管）
* 合否判定基準

## 試験手順書

## Gherkin format

* 前提 (given)
* もし (when)
* ならば (then)
* かつ (and)
* しかし (but)

## テストアンチパターン

### Unit Test Smells

#### テストが何もテストしていない

一見するとテストが有効に機能しているように見えるが、実はテスト対象をテストしていない

#### テストに過度なテスト準備が必要とされる

テストが環境をセットアップするのに長いコードを必要としている。こういうノイズがテストが本当にテストしたいのが何なのか？ということを分かりにくくする。

#### 大きすぎるテスト

有用だが大きすぎるテスト。たぶんテストが１つではなく複数の機能をチェックしているか、テストが１つ以上のことをやろうとしている(単一責任の原則に反している)

#### 内部をチェックしている

テストがテスト対象のコードの内部メソッド(privateやprotectedのメソッド)にまでアクセスしている。これはリファクタリングしにくくなる。

#### テストは開発者のマシンでしか動かない

テストが開発環境のみで動作し他で動かない。こういう問題を出来る限り早期に発見するため、継続的インテグレーションを利用すること。

#### テストが必要以上のことをチェックしている

テストが熱心という以上にチェックしている。こういうテストは本来チェックする必要のない箇所をちょっと変えただけで失敗することになってしまう。特にモックを利用していたり、ソートされていないコレクションの並び順をチェックするようなことをしていると発生しやすい。

#### アサーションの欠如

テストが何もアサーションを使っていない

#### チャットみたいなテスト

コンソールをテキストで埋めてしまうようなテスト。たぶん何かのチェックを手動で行うために使われているんだろう。。。

#### 例外を飲み込んでしまったテスト

テストが例外をキャッチして握り潰しテストを通している

#### テストがテスト用のfixtureと紐づいていない

#### 陳腐化したテスト

既にシステムで必要とされていない項目をチェックしている。そういうコードが参照されていると綺麗なプロダクションコードにすることが妨げられる

#### テスト内容が隠されている

テスト内容がセットアップメソッドや基底クラスやヘルパークラスに書かれている。テストはテストメソッドを見るだけで何をテストしているか把握可能であるべきである。テストは他の場所で初期化したりアサーションしたりしてはいけない。

#### 振る舞いとアサーションの混合

コードの実行結果をアサーションでチェックしている。最初にテスト対象のコードを実行してローカル変数に代入し、その値をアサーションでチェックしている。

#### 失敗した理由がわからない

テストを分割するかアサーションメッセージを使う必要がある。

#### 条件分岐のテストロジック

テストの中では条件分岐によるテストロジックは組み込むべきではない。そうしてしまうとテストが読みにくくなる。

#### 製品コードの中にテストロジックがある

テストが製品コード内の特殊ロジックに依存している。

#### 不安定なテスト

時々はテストに通るが、時々は環境等の理由で失敗する

### TDD Process Smells

#### ここ10分でGreenのバーを見ていない

出来る限り素早い頻繁なフィードバックを得るためには、小さいステップで進める必要がある。

#### 製品コードを書く前にテストを動かしていない

テストに失敗して初めて製品コードが必要となる。さらに驚くことにテストが失敗しなかったら、テストが本当に正しいのか確認すること。

#### リファクタリングに十分な時間を使っていない

リファクタリングは将来への投資である。可読性、変更容易性、拡張性となって返ってくる

#### テストするのが簡単すぎるものを飛ばす

想定ではなくてチェックすべきだ。もし機能が簡単ならテストもより簡単なんだから。

#### テストするのが難しすぎるものを飛ばす

よりシンプルにすること。さもないとバグが混入し、保守性が下がる。

#### 振る舞いではなくてメソッド中心にテストを構成している

メソッドのテストは壊れやすくリファクタリングキラーだ。テストは実際に使われる機能の小さなユースケースをテストすること。

#### コードカバレージをゴールにする

コードカバレージを不足しているテストの発見に使うこと。さもないとコードカバレージは増えたけれども不確かな役に立たないテストが増えたということになりかねない。

## エビデンスの取得方法

エビデンス取得を実施させる場合、エビデンスを取得する人とエビデンスを整理する人にわける。エビデンスを整理する人はエビデンスを確認したあと、「○○を確認した」という記載をいれるようにする。

## 自動テスト

### ディレクトリの種類

| ディレクトリ      | 説明                                     |
| ----------- | -------------------------------------- |
| unit        | モデル単体のテスト、ライブラリ単体のテスト                  |
| functional  | コントローラーのテスト                            |
| integration | 実際にユーザーが操作した時のような、複数のコントローラーにまたがる総合テスト |
| performance | パフォーマンステスト用らしいが、今回は割愛。                 |
| fixtures    | テストを実行する上で、予め DB に投入しておく検証用データのこと。     |
| prepare     | DBからスキーマをコピーするなど、テスト用のDBを準備する          |
