
単体テストとは
単体テスト(ユニットテストと呼ばれることもあります)は、プログラムを構成する比較的小さな単位(ユニット)が個々の機能を正しく果たしているかどうかを検証するテストです。
通常、関数やメソッドが単体テストの単位(ユニット)となります。
プログラムが全体として正しく動作しているかを検証する結合テストは、開発の比較的後の段階でQAチームなどによって行なわれることが多いのとは対照的に、単体テストは、コード作成時などの早い段階で開発者によって実施されることが多いのが特徴です。
1. 単体テストの利点

単体テストには、小単位で行われるからこそ得られるメリットがたくさんあります。
システム開発・ソフトウェア開発をスムーズに進めるためには、単体テストのメリットを把握して上手く使いこなすことが非常に重要です。
・不具合を発見し、修正・調整できる
単体テストは、モジュール・コンポーネントといった細かい単位でテストを行うため、バグ・不具合を発見しやすく問題個所の特定を行いやすいことが大きなメリットです。
テスト結果をもとに、プログラムの修正や調整もスムーズに行うことが可能です。
開発プロジェクトの要所で単体テストを実施することで、プログラムの動作を確認しながら質の高いシステム・ソフトウェアを作り上げていくことができます。
・リファクタリングを行いやすい
リファクタリングとは、システム・ソフトウェアの外部的挙動は変更せずに、プログラムの内部構造に変更や改善を加えることです。
コードの内部構造を最適な状態に保つためには重要な作業です。
単体テストの要件や実施内容を適切に準備します。外部的挙動に問題があった際にはテスト結果として検出されるため、リファクタリングをスムーズに行うことが可能です。
反対に単体テストの準備が不十分であれば、リファクタリングの実施が困難になるだけでなく、内部構造の劣化や工数の増加を招く恐れがあります。
このようにプログラムに変更を加える必要がある際の障壁を取り除けることも、単体テストを実施する大きなメリットです。
2. 単体テストの課題

単体テストを実施するにあたっては、デメリットや課題点もあります。
スムーズにテストを実施するためには、いかにデメリットや課題点を払拭するかがポイントです。
・準備に手間がかかる
単体テストは、プログラムの個々の機能や小単位での機能に対してテストケースを作成するため、準備に時間と手間がかかることが大きなデメリットです。テストケースを作成する数が多いほど、負担は大きくなります。
単体テストの準備には時間と手間がかかることは避けられないため、実施の際には十分な余力をもって臨むことが重要です。
・テストの品質はスキル次第
単体テストの品質は、テスト実施者のスキルにより品質が大きく左右されます。効果的なテストを実施するには、不具合が起こりやすい条件を想定したテストコードの作成やパラメーターの設定を行うことが重要となりますが、それには一定以上のスキルが必要不可欠です。
テスト実施者のスキルにより、テスト品質にばらつきがでてしまうことは、単体テストの実施に伴う大きな課題です。
・負荷を理由に実施を省略するケースも
単体テストの実施にあたっては、不具合を検出するためのテストケースの質と数を十分に確保することが重要です。手間と時間をかけて準備を行うほど、テスト品質の担保は行いやすくなります。
しかし、単体テストの準備・実施は負荷が大きいため、スケジュール・リソースを確保できずにある程度妥協したテストを実施せざるを得ない場合があります。
その場合は、テストの内容が不十分となり、品質の担保を満足にできないため注意が必要です。
どうしてもスケジュールやリソースが不足する場合は、テストケースの準備に優先順位付けを行うなど、次善の策を講じることも重要です。
3. 単体テスト(ユニットテスト)の仕組み

プログラム全体ではなく、プログラムを構成するモジュールを個別にテストするために、テスト対象のコードのほかに、ドライバーやスタブといった付加的なコードが必要になる場合があります。
・ドライバー
テスト対象のコードを呼び出すコードを代替します。・スタブ
テスト対象のコードが呼び出しているコードを代替するもので、呼び出し先のコードがまだ作成されていない場合などに使用します。単体テストでは、これらの仕組みによって、テスト対象の関数・メソッドをプログラムの他の部分や外部のコードから隔離して徹底的に検証できるという利点があります。
反面、これらの付加的なコードを作成したり管理するための負荷は、プロジェクトの規模が大きくなるほど、また改修を重ねて期間を経るほど増大します。
4. 単体テストの種類

テストケースを作成する際、何に着目するかという観点から見ると、単体テストは大きくホワイトボックステストとブラックボックステストに分類できます。
ホワイトボックステストは、テスト対象関数またはメソッドの内部構造に着目し、いっぽう、ブラックボックステストは、テスト対象関数またはメソッドの外から見た機能(入出力)に着目します。
・ホワイトボックステスト
テスト対象関数またはメソッドの内部構造に着目し、条件分岐や繰り返しなどの各部分を確実にテストします。関数・メソッド中のすべての命令を実行する命令網羅(ステートメントカバレッジ)、すべての分岐条件で真/偽の両方の分岐を通るようにする判定条件網羅(デシジョンカバレッジ、または分岐網羅、ブランチカバレッジとも呼ばれます)などがあります。
そのため、網羅率の測定(カバレッジ解析)や条件を網羅するためのテスト値の抽出などが必要になります。
・ブラックボックステスト
テスト対象関数またはメソッドの外から見た機能(入出力)に着目し、コードが期待される機能(仕様)を満たしているかどうかを検証します。仕様に関わる検証であるため、テストケースの作成や結果の確認には、人間による判断が必要になります。
5. 単体テストの自動化

単体テストは自動化することでより高い効果を期待できます。
自動化することで、多数のテストケースを漏れなく確実に実行できます。
また、毎晩すべてのテストケースをバッチで実行すると、前の日の変更によって既存のコードの動作にエラーが起きていないか、デグレードの有無を確認できます(回帰テスト、レグレッションテスト)。
単体テストの自動実行を可能にするテストフレームワークと呼ばれるものがあります。
よく知られているのは、Java言語用のJUnitですが、他のさまざまな言語用にもフレームワークが存在します。
・Java言語 …… JUnit
・C/C++言語 …… CppUnit
・.NET言語 …… NUnit
これらを総称して xUnitと呼ばれることがあります。
xUnitフレームワークは、テストの実行および結果の検証機能を提供します。
テストケースはすべてコードとして作成されるので、もちろん自動実行が可能です。
ただし、基本的にはテストケースの生成機能は提供しないため、自力でテストケースを作成する必要があります。
また、最近ではGoogleが提供するC++言語向けユニットテストフレームワーク Google C++ Testing Framework(Google Test)も有名です。
6. 単体テストと結合テストの違い
システム・ソフトウェアの開発プロジェクトでは、単体テストだけでなく結合テストも実施されます。ここでは、両者の違いについて解説します。
・単体テスト
小規模な機能単位で行われるテスト。各機能の動作確認を行い、後の工程へ繋げるのが主な目的。
・結合テスト
複数のモジュールを組み合わせて行われるテスト。仕様通りにプログラムが動作することを確認するのが目的。
単体テストではシステム・ソフトウェアの仕様の確認は行いませんが、結合テストでは仕様の確認まで行い品質を担保する点に大きな違いがあります。
単体テストでバグや不具合を取り除いて開発を進めた延長線上に結合テストが位置することにも留意しておきましょう。
7. まとめ
システム・ソフトウェア開発のプロジェクトでは、開発をスムーズに進めるためにも、動作保証や品質担保を行うためにも、単体テストを適宜実施することが重要です。
単体テストは準備や実施の負担が大きいため、十分なテストを行うためには効率化・自動化を意識して余力を生み出すことが重要なポイントとなります。