自動化されたテスト - 繰り返しいつでも実行できること
ユニットテストに限らず、ソフトウェアテストは可能な限り自動化するべきです。
つまり、
テストがプログラムとして繰り返し何度でも実行できる状態にします。
その結果、不具合などを早い段階でフィードバックでき、安心してリファクタリングや機能拡張を行うことができるようになります。
不安定なテスト - 結果が一定でないテストを避けること
ユニットテストでは、常にすべてのテストが成功している状態を維持することが望ましいです。
成功しないテストを放置する状態や実行ごとに成功するか失敗するかわからないテスト(不完全なテスト:例えば、現在時刻に依存するテストなど)がある状態は望ましくありません。
ドキュメントとしてのテスト - 仕様書として読めること
テストケースは、テスト対象のクラスやメソッドに対し開発者が想定しているさまざまなユースケースを記述したものです。また、テストが成功する限り、テストケースで定義されている動きは保証されています。したがって、テストケースは最も正確なドキュメントであり、テスト対象のサンプルコードです。
テストコードもプロダクションコードと同じようにメンテナンスし続ける必要があります。
常にテストコードを読む人を意識してテストコードを書くように心がけましょう。
問題の局所化 - テスト失敗時に問題を特定しやすいこと
テストケースは、十分に小さい単位で可能な限り多く作るべきです。
テストが十分に小さいならば、何らかの原因でテストが失敗したとしても、影響範囲と条件が絞りやすくなります。
不明瞭なテスト - 可読性の低いテストコードは避けること
テストケースにおいて、前提条件、実行、検証などが複雑に入り組んでいると、テストコードは非常に読みにくくなります。読みにくいコードはメンテナンス性も悪く、テストの質にも大きく影響を与えます。したがって、テストコードは可能な限りシンプルに分かりやすく記述するべきです。特に、各ステートメント(行)が、前提条件、実行、検証のどこに属しているかが明確な短いコードであるべきです。
前提条件は、同じコードが2回以上現れたならばsetUpメソッドに抽出します。同じテストクラスの中で2つ以上の前提条件が出現したならば、コンテキストごとのテストを検討してください。
テストのための「実行」は1つのテストケースで1だけ行うようにしてください。ある操作をして、別の操作をして、また別の操作をする、といったテストの実行フェーズを行うと、何が原因でテストが失敗したかがわかりにくくなります。このような場合は、前提となる前提条件を含め、テストする実行は1つの操作としてください。
検証も、1つのテストケースで1つだけ行うのが理想です。
独立したテスト - 実行順序に依存しないこと
テストケースは、可能な限りお互いに影響を与えないように定義すべきです。あるテストの結果やテストの実行順番がテストの結果に影響を与えるならば、テストケースの追加や削除により予期しない形でテストが失敗することになります。
テストを行いにくい設計を避けることも重要です。ハードコーディングされた設定ファイルを読み込むリソースやミュータブルなオブジェクトをシングルトンとして設計すると、この罠にはまりやすくなります。
参考: xUnit Test Patterns
最終更新:2016年01月21日 08:17