JUnit実践入門 2日目(ユニットテストについて)

ソフトウェアテストの概要とユニットテストの目的や基本となる概念について

ソフトウェア開発における「テスト」の定義:
「ある条件下においてソフトウェアの振る舞いを記録し、その記録が期待される結果となることを検証するプロセス」

学生の頃などに体験した「テスト」
問題として用意された質問に対して受験者が回答を行い、成績を出すプロセス。
→成績は受験者がどの程度の成績を持っているかの指標。問題に対する回答が決められているか、模範回答が存在する場合がほとんど。

ソフトウェア開発における「テスト」
検証する内容を定義し、ソフトウェアが期待どおりに動作するかを確認するプロセス。
→ソフトウェアの仕様や要件を元にテスト項目を作成する。ユーザビリティテストのように検証する項目が明確ではなく、人間の感覚に依存するテストもある。

定義から見るソフトウェアテストの重要なポイント3点
1.「ある条件下」という制約があること
→これは前提条件や事前条件と呼ばれる。前提条件が異なっていれば検証する内容も異なるため、テストでは前提条件が明確になっている必要がある。

2.「ソフトウェアの振る舞いを記録する」こと
→記録できなければ、期待される結果となることを検証できないため。

3.「期待される結果との検証を行う」こと
→つまり期待される結果がランダム性の高い振る舞いであればあるほど、テストは検証が難しくなる。

ソフトウェアテストの目的:
主な目的は品質管理。
→しかしながらソフトウェアテストではテストによって目的が異なるため、なんのためのテストであるかを意識するかが重要となる。

テスト技法
テストケースの作り方によってホワイトボックステストブラックボックステストの2つに大分類することができる。

ホワイトボックステスト
内部のロジックや使用を考慮してテストケースを設計する。
→したがって、ソフトウェアの内部構造とコードを理解しているプログラマが実施する。

ブラックボックステスト
内部構造について考慮せず、外部仕様のみからテストケースを作成する。
→プログラミングの知識よりも業務知識などが重要となる。

イメージとしてはこの記事に記載されているものが理解しやすい。
marikooota.hatenablog.com

ブラックボックステストの技法
同値テスト:ソフトウェアが同様の結果をもたらす値を同値クラスとしてグループ化し、各同値クラスからテストデータを選択するテスト技法。
境界値テスト:ソフトウェアが異なる結果をもたらす値(境界値)に着目し、境界値の近傍からテストデータを選択するテスト技法。

ユニットテストとは:
クラスやメソッドを対象としたプログラムを検証するためのテストであり、ソフトウェアテストの中ではもっと小さい粒度のテスト。
期待された振る舞いをするか検証し、テストが成功することによってそれを保証する。
「期待された振る舞い」=対照のクラスやメソッドの仕様

特徴:
ユニットテストはプログラムとして実行できる仕様書となる。
ユニットテストが成功する限り、正確な仕様書となる。
プログラムとしてユニットテストを行う場合、最初にテストコードを記述するコストはかかるが、実行するコストはほとんど必要ない。
したがって、何度でも実行できるし、テストを頻繁に実行することも可能となる。
→一方手動によるテストの場合にはテストの実行に大きな労力が必要になり、繰り返し実行することにコストがかかる。

実装コスト 手動テスト>自動テスト
実行コスト 手動テスト<自動テスト

目的:
仕様通りの振る舞いをするか保証する。
→しかしながら、直接の目的はソフトウェアの品質を高めることではない。
 ユニットテストを繰り返し何度も実行することで、プログラムに問題が発生した時に、早い段階で影響範囲などをチェックできる。
 つまり、対象のクラスやメソッドの仕様を動くプログラムとして記述することにより、仕様を明確にし、その仕様を保証すること。
 →改修を進めていくことによってプログラムに修正が入ったとしても仕様を担保することができるのはリグレッションの防止として役立ちそう。。

ドキュメントとしてのテスト:
テストケースは最も正確なドキュメントであり、テスト対象のサンプルコード。
なのでメンテナンスをし続ける必要があり、かつ常にテストコードを読む人を意識してテストコードを書く必要がある。

問題の局所化:
テストケースは十分に小さな単位で可能な限り多く作るべき。
→なんらかの原因でテストに失敗したとしても影響範囲と条件が絞り込みやすくなるため。迅速な原因特定につながる。

独立したテスト:
テストケースは可能な限りお互いに影響を与えないように定義すべき。
もしテストの結果やテストの実行順番がテストの結果に影響を与えるようならば、テストケースの追加や削除により予期しない形でテストが失敗する可能性が発生する。