
2006/5/28
■テスト駆動開発(TDD)を回すのにもノウハウが要る
TDDでは、いままでよりユニットテストコード作成にウェイトが置かれるので、ユニットテストコード作成の進ちょくがプロジェクトの進ちょくに与える影響は大きくなります。つまり、ユニットテストコード作成の効率性をより高めていかなくてはならないわけです。
では、ユニットテストコード作成の効率性を高めるには、具体的にどうすればよいでしょうか? まずは以下の2点を押さえるべきでしょう。
- EoTの高い設計になっていること
- テストコードが正確に業務仕様を表していること
まずは、「EoTの高い設計になっていること」について考えてみましょう。
EoTの高い設計をするためには、
- テストしやすいモジュール分割をする
- テスト時にMockを使用することを考慮して、インターフェイスを作成する
- 実クラスとMockクラスを容易に変更できるようにする(これは、DI[=Dependency Injection]を利用することで容易になりました)などの技法があります。
ところが、実際のプロジェクトでは、全員にこういった設計、実装を期待するのは、開発者が多ければ多いほど難しいですよね。筆者らは以下のような方法が有効だと考えています。導入自体、それほど難しくありません。
(A)最初に経験豊富な数人のメンバーで代表的なユースケースを設計・実装する。テストコードも十分に実装する
(B)そのコードをひな型にして、ほかのメンバーは担当するユースケースを設計・実装する
“Aでテストコードを十分に実装する”という条件がないなら、この方法を導入しているというプロジェクトは多いと思います。これは、プロジェクト全体の品質・粒度が一定になりやすい有効な方法です(特に開発者が多くなればなるほど)。
一般的に、Aは本格的な実装開始前に行うことが多く、そのスケジュールは非常にタイトです。結果として、テストコードの作成は行わないか、行っても簡素化されてしまいます。
しかし、Aで頑張ってテストコードもしっかりと作成すれば……、
- EoTの高い設計ができる。ほかのメンバーはこれを参照するので、ほかのメンバーの担当部分もEoTの高い設計になる
- ……そして、テストコードをひな型として使用できるため、プロジェクト全体でテストコードの書き方や粒度が合いやすい
となり、結果としてBの効率が上がるわけです。Aの開始をいままでより早めるなどスケジュールを調整して、Aでテストコードをしっかりと作成することをお勧めします。
次に、「テストコードが正確に業務仕様を表していること」について考えてみます。
- - PR -
理由は単純です。テストコードの内容がレビューされていないからです。本体のソースコードがテストコードを満たしていることは保証されます。そのテストコードが仕様に合致していることはレビューされたのでしょうか?
テストケースが押さえるべきところを押さえているか、仕様を誤解していないかなどを厳密にレビューできる人は、プロジェクト内において、少数であるケースが多いと思います。テストケースをきちんとレビューする際には、実は、テストレビュアーがボトルネックになりやすいのです。ということは、テストレビュアーたちには効率的にレビューしてもらうよう、対策を立てないといけません。
経験的には、各テストの内容を説明したテストケース一覧があると、チェックが効率的に行えるようです。テストケースの管理も容易になります。でも、そういった一覧をソースコードと別に管理するのはできれば避けたいところです。そんなときに、以下のようなアノテーションを使用するのが効果的です。
@TestSpecification( "3.入力値が、ログイン名=「Taro」、パスワード=「yyyyy」である。 |
| ※アノテーションの文字数が多いので、意図的に文字のポイントを小さくしています。(編集部) |
TestDocを定義しているソースは次のとおりです。
import java.lang.annotation.ElementType;
|
* @Documentedが設定されたアノテーションはjavadocの文章化の対象になるので、TestDocには@Documentedアノテーションを付けたいところですが、日本語が文字化けするようなので付けていません。
AnnotationProcessorインターフェイスなどを使用すれば、アノテーション情報を読み出せます。その情報をエクセルやCSV形式に変換するプログラムを作成して、テストケース一覧表を作成することができます。また、javadocコメントにテストケースを記載する場合、開発者ごとに書く内容が異なりやすいのですが、この方法なら開発者ごとのずれは発生しにくいといった効果も期待できます。
■ユーザーI/Fはどうするんだ?
業務システムにTDDを適用しようとしても、ユーザーI/F回りは適用しづらい領域と一般にいわれています。ユーザーI/F回りはTDDの領域から除外すべきだという意見も多いようです。理由はビジネスロジックと違い、ユーザーI/Fは人間の介在が前提となっているために、テストコードが書きにくいからです。しかし、業務システムにおいては実はこの部分のテストに占める割合は大きいのです。テスト工数が大きいということは、テスト駆動開発がうまく導入できた場合には、その恩恵も大きいということになります。
もし、ユーザーI/F部分にもテスト駆動開発を導入するとすれば、先に挙げた2つのポイント
- EoTの高い設計になっていること
- テストコードが正確に業務仕様を表していること
に加え、
- テストをしやすくするツールを利用する
を検討しなければなりません。
いままでユーザーI/Fにはテスト駆動開発が適用しづらいといわれてきている理由の1つに、ちょうどよいツールがあまりなかった、という点があると思います。ユーザーI/Fのテスト自動化ツールとしては一般的にマウス操作の記録・再生方式が主流なのですが、この方式ではそもそもテスト駆動開発が目指している設計文書(実装する前の設計文書)としての役割が担えません。つまり低レベルのマウスの動きやマウスボタンのプッシュ・リリースではなく、意味論的な観点で各コンポーネントに対する操作をテストシナリオとして記述したいのです。
例えばリストを選択するために隠れている部分をスクロールする、などといった動作は人間の頭ではあたりまえのように処理していて、意識していません。テストシナリオを書く場合も同じことで、選択対象の項目が隠れている、いないに係らず、単純に「リストのこの項目を選択する」と記述したいわけです。単なるスクロールのテストをするということでなければ、テストシナリオには書かずとも対象の項目をちゃんとスクロールして見えるようにしてから選択する、というレベルのことは自動的に処理してくれるようなテストツールが必要です。
また、テストケースが設計文章の役割をするためには、チームの全員が設計文章を作成できる、つまり全員がユーザーI/Fのテストを作成できる、手軽に使えるものであることが望まれます。
筆者の1人(安中)はこの問題に取り組むために、SwingUnitという、Java SwingアプリケーションのユーザーI/Fのテスト自動化のためのツールをjava.net上で開発中です。興味のある方はぜひチェックしてみてください。
テスト駆動開発を導入するには、「EoTの高い設計になっていること」「テストコードが正確に業務仕様を表していること」「テストをしやすくするツールを利用する」という3つのポイントに気を付けるべきだ。
テスト駆動開発で行こう! バックナンバー 連載インデックスへ»
- 第1回 テストを金額にするといくら?
- 第2回 テスト駆動を導入するための3つのポイント
ホワイトペーパー(TechTargetジャパン)
|
|

