テスト駆動開発とは?メリット・デメリットやサイクルの詳細など
COLUMN
最終更新日:2023年06月12日 / 投稿日:2022年11月04日
システム開発・プログラム開発の手法にはさまざまなものがあり、テストファーストをベースとした開発手法を「テスト駆動開発」と言います。テスト駆動開発にはメリット・デメリットがあるだけでなく、ある3つの作業サイクルを繰り返してプログラミングを進めていかなければならないため、実施する際はそれぞれの知識を習得しておく必要があるでしょう。
また、テスト駆動開発を実施する際には注意点とも言えるいくつかのポイントもあります。そこで今回は、テスト駆動開発の概要やメリット・デメリットから、3つの作業サイクルの詳細、実施時のポイント・注意点まで具体的に説明します。
目次
1. テスト駆動開発とは?
テスト駆動開発とは、プログラムの実装前にテストコードを記述し、そのテストが問題なく動作する最低限の実装を行ったのち、修正と実装といった短いサイクルを何度も繰り返して、最終的なプログラムの成長・実装を行う開発手法です。英文では「Test-Driven Development」と言い、「TDD」と略称されています。
テスト駆動開発は、テストファーストをベースに開発を進める手法であることから、テスターが行うテストと混同されるケースも少なくありません。しかし、テスターが行うテストは何らかの問題点を見つけるための手法である一方、テスト駆動開発は開発を計画通りに進めるため、いわゆる動作チェックを主な目的とした開発プロセスです。大きな違いのある2つのテストの混同・誤解を避けるため、「振る舞い駆動開発(BDD)」とも呼ばれています。
また、テスト駆動開発にはメリット・デメリットがあります。ここからは、テスト駆動開発のメリット・デメリットをそれぞれ詳しく紹介します。
1-1. テスト駆動開発のメリット
● 仕様への理解が深まる
テストコードを正しく作成するためには、開発者がシステムの要件・仕様を細かに把握することが必須です。テスト駆動開発は、あらゆる機能の追加・修正を重ねながらテスト実装を繰り返すという過程において、そのシステムを段階的に、かつ網羅的に理解できるようになる点がメリットです。
● 不具合の発見・修正が初期段階で可能となる
テスト駆動開発を行うことで、開発の初期段階からあらゆる不具合を検知できるようになります。加えて、プログラム規模も小さいために修正も比較的容易であり、のちの工程にまで不具合を持ち越すことがほとんどないという点は、テスト駆動開発の大きなメリットでしょう。
● 開発者の不安や心理的負担が軽減される
APIテストの継続をスムーズに行うためには、API自動テスト駆動開発は、最低限の機能からテストを繰り返しつつ、着実に開発まで進めます。追加のコーディングやリファクタリングを行う上で異常がないかどうかを確認しながらシステム構築を進められるため、「プログラムを壊してしまうかもしれない」という心配はほとんどありません。このように、開発者の不安や心理的負担が軽減される点も、テスト駆動開発の大きなメリットとなるでしょう。
1-1. テスト駆動開発のデメリット
テスト駆動開発のデメリットは、下記の通りです。
● テストコードの保守・管理にコストを要する
テスト駆動開発では、一度書いたテストコードの保守が必要です。また、保守後に大きな仕様の変更が起きた場合はテストコードを修正しなければなりません。保守・管理には特に人的コストが多く発生することを覚えておきましょう。
● 慣れるまでに時間を要する
これまでの開発手法からテスト駆動開発に切り替えるには、多くの時間と労力が必要です。望み通りのテストコードを書くためには、ある程度慣れておかなければなりません。初期段階ではテストコードを書くだけでも多大な時間がかかるだけでなく、その分開発者の負担も大きくなることも覚えておきましょう。
2. テスト駆動開発の3サイクルの詳細
テスト駆動開発は、基本的に「レッド」「グリーン」「リファクタリング」の3つのサイクルで進められます。これらのサイクルを理解し、かつ「一連の流れ」として繰り返さなければ、プログラムを着実に開発することができません。
ここからは、各サイクルの詳細について解説します。
2-1.レッド
レッドは、「エラーが出ることを前提に、動作しない・失敗するテストコードを書く」という工程です。テストツールの利用時、テストに失敗すると赤色のエラーが表示されることから、レッドと名付けられました。
テスト駆動開発において必ずファーストステップとなるサイクルであり、実装したい機能を実現できないテストコードであっても書くことが基本となっています。当然正常に動作せずエラー表示が出てきますが、テスト駆動開発の流れとしては失敗ではなく、むしろ成功です。
2-2.グリーン
グリーンは、「レッドのサイクルで失敗したテストコードをもとに、動作するテストコードを書く」という工程です。この工程では、完璧なテストコードではなく、どれほど直接的でシンプルな手段であっても、設定したさまざまなテスト条件をクリアさせられる程度の、いわゆる最低限のテストコードを書くことがポイントとなります。/
最終的に目指す状態はきれいで完璧なコードですが、完璧なコードに導くためにも、方法は問わずにただテストが成功する程度のコード記述が欠かせません。最終段階でよりよいコードを書くためにも、レッド・グリーンの工程を数回繰り返すケースもあります。
2-3.リファクタリング
リファクタリングは、「グリーンのサイクルで書いたテストコードの保守性と可読性を高める」という工程です。テストにパスできることを確認しつつ、グリーンのサイクルで書いたテストコードの重複を取り除いたり変数名を直したりして、適切な完成形に近付けていきます。
このとき、グリーンのサイクルですでにテストをパスしていることを理由に、リファクタリングを後回しにするケースも珍しくありません。しかし、リファクタリングを後回しにするとプログラムの規模が大きくなった際に修正負担も大きくなるため、グリーンの段階を達成したときは都度リファクタリングを行うことが重要です。
なお、リファクタリングが完了してもプログラミングの実装が完了しない場合は、再度レッドの工程に戻って新たなテストコードを追加していくこととなります。
3.テスト駆動開発を実施する際のポイント・注意点
テスト駆動開発を実施する際は、テストを実行しやすい環境整備が必須です。実行に数秒かかるようなフレームワークや柔軟性の低いフレームワークは効率性が大きく低下する要因にもなり得るため、スムーズかつ簡潔にテストを実装・実行できるユニットテスト環境を整えるようにしましょう。
また、テスト駆動開発に重要なのは事前の環境整備だけではありません。実践時にも注意点と言えるいくつかのポイントがあることに留意しましょう。
3-1.導入箇所を限定する
テスト駆動開発では実装時にさまざまなテストコードを書くことから、コーディングに多大な時間を要する可能性もあります。レッドの工程では短期間で実装しなければならないことも多く、疎かになったためにうまく機能しないといったケースもあり得ます。
そのため、テスト駆動開発の導入箇所を限定することが重要です。導入すべき部分・あえて導入しない部分を見極めることで、開発時間を効率化できるだけでなく、実装が進むにつれて範囲が広まるプログラム・テストコードのメンテナンス時間の短縮も期待できるでしょう。
なお、リファクタリングが完了してもプログラミングの実装が完了しない場合は、再度レッドの工程に戻って新たなテストコードを追加していくこととなります。
3-2.開発サイクルの遵守・レビューを徹底する
テストを実施する際は、プログラム開発における必要条件を満たすためにも、テスト項目をあらかじめ設定しなければなりません。このとき、テスト項目が不十分だと最終段階まで不具合を見落とすおそれがあります。不具合の検知が遅れれば遅れるほど、修正に多大な時間を要するため注意が必要です。
テスト項目の漏れを最大限防ぐためには、3つの開発サイクルを遵守し、テストコードそのもののレビューを徹底することもおすすめします。開発サイクルをしっかりと繰り返すことによって抜け・漏れに気付けるだけでなく、経験者によるテストコードのレビューを実施することで、より客観的な視点から項目の網羅性を判断してもらえます。
3-3.開発サイクルの遵守・レビューを徹底する
テスト駆動開発をスムーズに進めるためには、テスト間における依存関係をなるべく排除することが重要です。テスト間における依存関係がある場合、不具合の検知による修正・追加を行ったとき、無関係なテストにも失敗する可能性があります。
テスト間の依存関係を排除するためには、モックの活用が有効です。モックとは「モックアップ」の略称であり、テスト駆動開発においてはいわゆる「模擬・模型」を指します。隣接するオブジェクトとどのように連携するのかを確かめるためのもので、モックライブラリを有効に活用するケースも一般的です。
まとめ
テスト駆動開発(TDD)とは、最低限のテスト実装後、修正・実装の短い開発サイクルを繰り返して、最終的なプログラムの成長・実装を行う開発手法です。テスターの行うテストとの混同を避けるために、「振る舞い駆動開発(BDD)」と呼ばれることもあります。
テスト駆動開発には、システムの仕様の理解が深まる・開発者のあらゆる負担が軽減されるといった大きなメリットがある一方で、慣れるまでに時間やコストを要する可能性があるというデメリットもあります。
テスト駆動開発を実施する際は、テストの実行がしやすい環境を整備することが欠かせません。加えて、導入箇所を限定して開発サイクルを遵守したり、テスト間における依存関係をしっかり排除したりすることも重要です。ここまでの内容を参考に、スムーズなプログラミング実装の実現に向けて、ぜひテスト駆動開発を進めてみてください。