(Photo by:Berliner.Gazette)
はじめに
テスト駆動開発(TDD)をご存知ですか?2000年代初期に開発手法として確立され、10年ほど前から普及してきているため、知っている方も多いのではないでしょうか?IT業界で10年以上というと古臭い感じがしますが、まだまだ有効な手段です。
この記事では、テスト駆動開発(TDD)を始めてみようと思っている方のために、テスト駆動開発(TDD)の概要とメリット・デメリット、注意点などについてお伝えしていきます。ぜひご一読して、プロジェクトをより良いものにしていってください。
TDDの概要
テスト駆動開発(TDD)は開発手法のひとつで、実装コードを書く前にテストコードを書きます(テストファースト)。しかし、これは従来のユニットテストを先に書くということではありません。簡単に言うと、必要最低限の単純な実装からインクリメンタルに実装とテストを書いていくことで、最終的な実装コードを完成させます。つまり、一気に実装するのではなく、小さなテストを積み重ねていって、少しずつ確実に実装するのです。詳細については、後で説明します。
なんのためにTDDをするのか?
それでは、いったいなんのためにTDDを行うのでしょうか?TDDの目的は、主に2つあります。
ひとつ目は、コード(設計)を綺麗にすることです。汚いコードや設計が悪いコードは、バグを生みやすい上、テストもしづらいです。TDDでは、テストと実装を同時に書くことで、そもそもテストしづらいコードが生まれにくくなり、コードが綺麗になっていきます。
ふたつ目は、フィードバックの高速化です。実装の前にテストを書くことで、実装が正しいのかすぐに確かめられます。また、実装直後はコードの記憶が明確ですから、すぐに修正することができます。このため、何週間(もしくは何ヶ月)も後にバグのあるコードを読まずに済みます。
TDDはこの2つの目的を達成することによって、さまざまなメリットを生み出します。
TDDのメリット
バグが少なくなる
TDDのテストによって、多数のバグが開発段階で発見・修正されるので、後々発見されるバグの数がかなり少なくなります。マイクロソフトリサーチによると、TDDを採用したVisual Studioの開発では実に90%ものバグの削減に成功したと述べられています。
デバッグの時間が短くなる
テストファーストによりバグを早期に発見することで、修正までの間隔が短くなり、結果的にデバッグの時間も短くなります。誰でも3ヶ月前に書いたコードのバグ修正をするのは嫌ですよね?バグはできるだけ早く見つけるのが賢明です。
要件への理解が早まる
インクリメンタルにテストと実装を繰り返すため、実装対象への理解が徐々に深められます。そのため、初期の段階では要件があまり理解できていない部分に適用すると効果的です。
リグレッション(回帰)テストができる
TDDにより作成されたテストは、リグレッションテストにも役立ちます。リグレッションテストは、機能の追加やバグの修正をした際に、修正と無関係な部分を壊していないかチェックするテストです。良質なテストは、開発者に安心感を与えてくれます。
TDDのデメリット
実践するには慣れが必要
最大のデメリットは、慣れ親しんだ開発手法からTDDに切り替えるには時間がかかるということです。特に今までテストをしたことがない方にとっては、難しく感じられるかもしれません。また、TDDへの理解が浅いと、TDDモドキになってしまい、うまくいかないことが多いです。
コーディング時間が伸びる
実装時にテストを書くため、必然的にコーディング時間が伸びます。あまりにも時間がない場合は、テストファーストがおろそかになってしまい、TDDが破綻します。もちろん、正しくTDDを行えば、バグ対応に追われる時間を削減でき、結果的に早くプロジェクトが完了します。
テストするのが難しいこともある
どうがんばっても、テストをするのが難しい部分はあります。特に、データベースまわりやI/Oまわりです。あまり時間をかけてもメリットが少ないと判断した部分については、テストしないという選択もありです。TDDの目的は、テストすることではありません。すべてをテストしようと思わないでください。本当のテストは、品質テストに任せましょう。
テストコードを保守する必要がある
TDDで生み出されたテストコードは、実装コード同様に保守する必要があります。上でも説明しましたが、リグレッションテストに使うためです。そのため、通常より保守するコード量が増え、大きな変更が入った場合には多くのテストを修正しなければならないこともあります。しかし、これは保守性とのトレードオフなので仕方がありません。
基本的なTDDの流れ
TDDは、「レッド → グリーン → リファクタリング」と3つのサイクルを繰り返すことで、実装コードとテストコードをインクリメンタルに構築していきます。
最初のレッドは、テストを書いて失敗させるサイクルです。まずは、実装するコードのテストをひとつだけ書きましょう。書いたテストは、実行して失敗することを確かめます。最初からパスするテストを書いてはいけません。
次のグリーンは、実装コードを書いてテストにパスするサイクルです。レッドで書いたテストをパスするのに”最低限必要なコード”を書きます。最初は固定値を返すなどしますが、サイクルを繰り返すごとに、徐々にロジックを追加していきます。
最後のリファクタリングは、コードを綺麗にするサイクルです。グリーンで書いたコードが汚ければテストにパスする状態を維持したまま、コードを綺麗にしましょう。また、テストコードも綺麗でなければいけません。適宜、リファクタリングしましょう。
3つのサイクルを終えても実装が完了していなければ、レッドに戻り新しいテストを追加します。これを、実装が完了するまで繰り返します。
TDDで失敗しないための注意点
テスト実行時間はできるだけ短くする
TDDを続けていくと、どんどんテストが増えていきますが、テスト時間は一定の範囲内に収まるようにしておきましょう。テストするたびにコーヒーブレイクが必要なようでは、開発時間がいくらあっても足りません。そのため、DBやI/Oなど時間がかかる部分は切り離す必要があります。
各テスト間に依存関係を持たせない
各テスト間に依存関係があると、修正や変更を行ったときに、無関係なテストまで失敗するといったことが起きてしまいます。一気に多数のテストが失敗するとゲンナリします(気分はブルーですがテストは真っ赤です)。モックライブラリなどを活用して、テスト間の依存関係を排除しましょう。
まとめ
TDDは、ソフトウェアの品質を改善するための良い手段になります。まだやったことがない方は、一度小規模なプロジェクトで試してみてください。以前にやったことがある方も、もう一度TDDの価値を見なおしてみませんか?TDDがある程度理解できたら、派生系のBDD(ビヘイビア駆動開発)に進んでみるものよいでしょう。あなたはどんな開発手法を使いますか?
本ブログは、Git / Subversion のクラウド型ホスティングサービス「tracpath(トラックパス)」を提供している株式会社オープングルーヴが運営しています。
開発の効率化をしたい!もっと便利なツールを使いたい!そんなお悩みをtracpathで解決!
「tracpath(トラックパス)」は、企業内の情報システム部門や、ソフトウェア開発・アプリケーション開発チームに対して、開発の効率化を支援し、品質向上を実現します。
さらに、システム運用の効率化・自動化支援サービスも提供しています。
”つくる情熱を支えるサービス”を提供し、まるで専属のインフラエンジニアのように、あなたのチームを支えていきます。
No Comments