テスト

テストはソフトウェア開発の重要な部分です。 気付いているか否かにかかわらず、私たちは継続的にテストをしています。 例えば、PHP でクラスを書くとき、私たちはステップごとにデバッグしたり、または単純に echo 文や die 文を使ったりして、実装が最初の計画通りに動作することを確認します。 ウェブアプリケーションの場合は、何らかのテストデータをフォームに入力して、ページがユーザと期待通りの相互作用をすることを確認します。 テストを実行するプロセスを自動化して、何かを確認する必要があるときは、いつでも、それを代行してくれるコードを呼び出す必要があるだけにすることが出来ます。 結果が計画したものと合致することを確認するコードがテストと呼ばれ、それを作成して更に実行するプロセスがテスト自動化として知られています。 このテストの章の主題は、このテストの自動化です。

テストとともに開発する

テスト駆動開発 (TDD) とビヘイビア駆動開発 (BDD) のソフトウェア開発手法においては、実際のコードを書く前に、コードの断片または全体の機能の振る舞いを一連のシナリオまたはテストとして記述します。 そして、その後で初めて、意図された振る舞いが達成されていることを確認するテストに合格する実装を作成します。

一つの機能を開発するプロセスは以下のようになります。

  • 実装されるべき機能を記述するテストを作成する。
  • 新しいテストを走らせて、失敗することを確認する。 まだ実装がないので、これは予期された結果です。
  • 新しいテストに合格するための単純なコードを書く。
  • 全てのテストを走らせて、全てが合格することを確認する。
  • コードを改良して、それでも全てのテストが OK であることを確認する。

完了すれば、別の機能または改良のために、このプロセスを再び繰り返します。 既存の機能が変更される場合は、テストも変更されなければなりません。

Tip: 多数の小さくて単純なイテレーションを繰り返すために時間を取られていると感じる場合は、テストシナリオのカバー範囲を広くして、テストを再度実行するまでの作業量を増やしてみてください。 デバッグばかりやっている場合は、逆に範囲を狭めてみてください。

全ての実装作業の前にテストを作成する理由は、そうすれば、その後で、達成したい事柄に集中して「どのようにするか」に没頭することが出来るからです。 通常、そのようにすることは、良い抽象化、機能修正時の容易なテスト保守、また、結合度の低いコンポーネントにつながります。

ですから、このような手法の長所を要約すると次のようになります。

  • 一時に一つの事柄に集中できるため、計画と実装がより良いものになる。
  • より多くの機能をより詳細にテストでカバーできる。つまり、テストが OK なら何も問題がないと期待できる。

通常は、長い期間で見れば、かなり時間を節約する効果があります。

Tip: ソフトウェアの要求仕様の取り纏めと対象事物のモデリングに関する原則について更に知りたい場合は、ドメイン駆動設計 (DDD) を学習するのが良いでしょう。

いつ、どうやって、テストするか

上記で説明したテストファーストの手法は長期間にわたる比較的複雑なプロジェクトには合理的なものですが、簡単なプロジェクトでは、やりすぎとなるおそれもあります。 この手法が適切であることを示す兆候は、いくつかあります。

  • プロジェクトは既に大きくて複雑である。
  • プロジェクトの要求仕様が複雑になってきている。プロジェクトが継続的に大きくなっている。
  • プロジェクトが長期にわたる予定である。
  • 失敗のコストが高すぎる。

既存の実装の振る舞いをカバーするテストを作成することは、何も悪いことではありません。

  • プロジェクトはレガシーなもので、段階的な刷新が予定されている。
  • 従事すべきプロジェクトを得たが、それにはテストがなかった。

どんな形式の自動化テストもやりすぎになる、という場合もあり得ます。

  • プロジェクトは単純で、この先も、複雑になる心配はない。
  • これ以上かかわることはない一時的なプロジェクトである。

このような場合であっても、時間に余裕があれば、テストを自動化することは良いことです。

参照

  • Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.