単体テストとは? ~種類や観点、やり方まで詳しく解説~

単体テストとは、プログラムを組んだモジュールやコンポーネントといった機能単位の動作などを単体で確認するテストのことです。システム開発におけるテスト工程の一つで、結合テストや総合テスト、運用テストの前に行われます。
結合テストなどに先駆けて単体テストを実施しておくことで、不具合の原因を特定しやすく、その分、修正も容易です。テスト工程で欠かすことのできないテストです。
本コラムでは、単体テストの実施方法やメリット、デメリットなどについてご紹介いたします。

単体テストとは
単体テストとは、プログラムを組んだモジュールやコンポーネントといった機能単位の動作などを、単体で確認するテストのことです。ユニットテストとも呼ばれます。
システム開発は、企画、要件定義、設計、構築、テスト、リリース、運用・保守という流れで行います。このうちテスト工程をさらに細分化すると、単体テスト(ユニットテスト)、結合テスト、総合テスト(システムテスト)、運用テストというプロセスを取ります。
つまり、単体テストはテスト工程で最初に実施するテストということです。
プログラミングを担当した技術者がプログラムを組んだ直後に行うことから、その機能がどのような動作をするべきかというイメージが鮮明な状態でテストが行えるため、精度の高い検証効果が期待できます。
単体テストで不具合を徹底的に修正しておくことで、以降のテスト工程での手戻りを防ぐことが可能です。
単体テストを重視する場合、実装後に単体テストを行うのではなく、単体テストを行ってから実装する「テスト駆動開発(TDD/ Test-Driven Development)」が採用されるケースもあります。
単体テストと結合テストの違い
一方、結合テストとは、単体テストの次に行うテスト工程で、機能単位を組み合わせて、意図した通りの動作をするかどうかを確認するテストです。
結合テストでスムーズに検証を行うためにも、単体テストでは漏れのない検証を行う必要があります。
単体テストの仕組み
単体テストは単体での動作を保証するために行うテストですが、実際にシステムがリリースされた際に、それ単体で動作させるケースはほぼ皆無です。
そこで、「テスト対象」に、ほかの機能の代わりとなる「ドライバー」と「スタブ」を組み合わせてテストを実施します。
ドライバー
ドライバーとは、テスト対象を呼び出す役割を持つ、上位モジュールの代替品のことです。
スタブ
スタブとは、テスト対象が動作した際に呼び出す先の下位モジュールの代替品のことです。
単体テストの種類と観点
システム開発におけるテストには、ソースコードが明らかな状態で行う「ホワイトボックステスト」と、ソースコードが不明な状態で行う「ブラックボックステスト」の2種類があります。
このうち、単体テストでは主に「ホワイトボックステスト」が使われますが、ブラックボックステストも併用することで、内部仕様と外部仕様のずれを見つけることができるようになります。
ホワイトボックステストとは
ソースコードが明らかな状態で行うテスト方法をホワイトボックステストといいます。
ホワイトボックステストでは、対象となるプログラムの内部構造に着目します。このため、テスト実施者にはプログラミングに関する知識が必要不可欠です。
ホワイトボックステストには、主な技法として「制御フローテスト」と「データフローテスト」があります。
制御フローテスト
テスト対象となるプログラムのソースコードには、分岐条件が含まれることが多いです。
制御フローテストとは、その分岐条件に特定データを設定することで、設計通りの動作を確認する手法です。
一般的に、テスト対象は複数の分岐条件を持つため、すべてのパターンをテストしようと思えば膨大なテストを行わなくてはなりません。
そこで、すべての処理経路を一度は通るように、可能な限り多くのテストパターンを設定することになります。
データフローテスト
制御フローテストが処理経路に着目したテスト手法であるのに対し、データフローテストではデータの流れに着目します。
プログラム内で使用されるデータには、定義→使用→消滅というライフサイクルがあり、これをデータフローと呼びます。ただ、プログラムをよく確認してみると、「定義→定義」「消滅→消滅」のような、エラーが出る可能性のあるパターンが見つかることがあります。このようなパターンをチェックするのがデータフローテストの目的です。
ブラックボックステスト
ブラックボックステストとは、ホワイトテストとは逆に、ソースコードが不明な状態で行うテスト方法です。
テスト対象に期待する動作(仕様書で求められている動作)を検証するもので、モジュール内でデータがどのように処理されるには着目せず、入力と出力の整合性にのみ着目します。
このため、ブラックボックステストにはコーディングのスキルは不要で、ソフトウェアテストのスキルがあれば実施できます。
前述のように、ホワイトボックステストとブラックボックステストを併用することで、内部仕様(プログラムの仕様)と外部仕様(インターフェースやシステム全体、主要機能などの仕様)のずれを検出できます。
単体テストのやり方
単体テストを実施する際は、以下の流れを取ります。
仕様書を作成する
どのモジュールにテストコードを作成するかを計画し、テストの一覧を作成します。
この段階で、テストコードも作成します。
単体テストを実施する
仕様書に基づいて、実際にテストコードを実施します。
結果を記録する
実施した単体テストの結果を記録します。
実行結果は「エビデンス」と呼ばれます。ログや、入出力したファイルも併せてエビデンスとして保存しておきます。
テスト結果がNGだった場合は、プログラムを修正して、再度、単体テストを行います。
単体テストのメリット・デメリット
単体テストには、メリットもデメリットもあります。
以下でそれぞれ、ご紹介いたします。
単体テストのメリット
単体テストには、以下の5つのメリットがあります。
テスト結果がNGだった場合の修正が容易
単体テストの結果、意図した動作をしないことがわかった場合にも、単体テストが最小単位で行われることから、問題の個所の特定や修正がしやすい点がメリットです。
低コストでスピーディに結果が得られる
結合テストなどを比べると、単体テストは自動化しやすく、高速で実施できます。
このため、コーディングの担当者がコードを作成・修正するたびにテストを実行でき、結果も数秒で得られます。
リファクタリングが行いやすい
リファクタリングとは、プログラムの動作は変えずにソースコードだけを整理して書き換えることです。
単体テストを行うことで確実に動作確認が行えるため、大胆なリファクタリングもしやすくなります。
コードを理解するドキュメントとして活用できる
単体テストを行う際に作成したテストコードを、実行結果が書かれたドキュメントと捉えることもできます。以降、コードを読む際の助けになります。
アジャイル開発に向いている
単体テストは、不具合やデグレードが発生した場合にも問題個所を即座に特定できます。また、リファクタリングが行いやすいことから、技術的負債が蓄積しづらくなります。
このため、仕様変更が頻繫に発生する開発で採用されるアジャイル開発との相性が良い点もメリットです。
単体テストのデメリット
一方、単体テストにもデメリットはあります。
主に以下の2つです。
テストコードを作成するのに工数がかかる
「低コストでスピーディに結果が得られる」でお伝えしたように、単体テストはテストフレームワークの活用によって自動化することができます。しかし、テストコードの生成は、自動化することができません。コーディング担当者が、一つひとつ、テストコードを作成しなくてはならないため、ここに工数がかかります。
自動化については、「単体テストの自動化」で詳しくご紹介いたします。
テストの精度が実施者のスキルに依存する
前項とも関連しますが、テストコードを書く際にはコーディングやテストのスキルが求められます。
コーディング担当者がテストまで実施するため、コーディングについては、そこまで大きな差はつかないかもしれません。
ただ、テストの仕様書作成には、スキルが必要です。
単体テストでは、結合テストなど、後のテスト工程で、単体テストで検証できるはずだった不具合を出さないことが大切です。
しかし、たとえば、「制御フローテスト」では、できるだけ多くのテストパターンを試す必要がある一方で時間は限られているため、いかに最適なパターンを作成し、組み合わせるかが重要になってくるのです。
単体テストの自動化
前述のように、単体テストは自動化することが可能です。
単体テストを自動化することで、短時間でたくさんのテストを実行できたり、夜間にバッチ処理するなど業務時間外にテストを実施できたり、ヒューマンエラーを防止したりできます。
単体テストの自動化には、テストフレームワークを活用します。
テストフレームワークには、Javaに対応するJunit、PHPに対応するPHPUnit、Pythonに対応するPyUnitなどがあります。
単体テスト実施の際の注意点
単体テストを実施する際は、「テスト範囲を明確にしておくこと」と「テスト結果を記録すること」に注意しましょう
テスト範囲を明確にしておく
単体テストでは、テストパターンを増やすほど、不具合を見つけられる可能性も高まります。しかし、時間は有限なため、検証すべきテスト範囲を限定する必要があります。
そのためにも、単体テストで検証できることと、できないことを理解した上で、計画書や仕様書を作成することが大切です。
単体テストで検証できること
- テスト対象のプログラムを実行した際に期待通りの返り値が出るかどうか
- テスト対象のプログラムを実行した際に例外が発生するかどうか
- テスト対象のプログラムを実行した際に発生する副作用は想定通りか
単体テストでは検証できないこと
- テスト対象のプログラムのパフォーマンスが十分かどうか
- テスト対象のプログラムを修正で、システムの仕様が修正されたかどうか
テスト結果を記録する
「単体テストのやり方」でお伝えしたように、単体テストを実施した後は、その結果を記録することが大切です。
記録する目的の一つは、たしかにそのテストを実施したという証拠を残すためです。テストから時間が経過すると、仕様書に記載されているどのテストが実施済みなのか、未実施なのかという記憶が曖昧になることもあります。
もう一つは、テストの実施者とは別のエンジニアが記録を見て、そのテストの結果が正しいものかどうかをチェックできるためです。たとえば、テスト実施者が「OK」と判断したものが、実は「NG」だったという可能性もあるのです。
また、単体テストの結果をきちんと記録しておくことで、次のテスト工程でNGが出た部分の単体テストで、確かに結果がOKだったことを確認できる点でも重要です。
まとめ
単体テストは、ソフトウェア開発のプロセスにおけるテスト工程の中で、最初に実施されるもので、モジュールやコンポーネントといった機能単位での動作に問題がないかどうかを確認します。
単体テストにはホワイトボックステストとブラックボックステストを併用することで、外部仕様と内部仕様に乖離がないことを検出します。
単体テスト実施の際には、テスト範囲を明確にすることや、記録を必ず残すことなどに注意しましょう。
Concept Book
ローコード開発・業務プロセスのデジタル化で豊富な実績を持つintra-martが、お客様のビジネスにどのような効果をもたらすのか、特長や導入効果など製品コンセプトを詳しくご紹介しています。

お困りごとがありましたら、お気軽にご相談頂ければと思います。