ナレッジ

単体テストと結合テストの違い。定義や考え方、具体的なやり方を解説

単体テストと結合テストの違い。定義や考え方、具体的なやり方を解説

ソフトウェア開発において品質を左右する重要な工程が「テスト」です。

中でも単体テストと結合テストは、不具合を早期に発見し、手戻りや修正コストを最小限に抑えるために欠かせないテストレベルです。

しかし、それぞれの違いや目的や役割を十分に理解しないまま進めてしまうケースも少なくありません。

本記事では、単体テストと結合テストの定義や役割の違いを整理し、メリット・デメリット、具体的な進め方までを分かりやすく解説します。

テストレベルとは

ソフトウェアテストは、開発プロセスにおける重要な工程であり、プロダクトやサービスが要求通りに動作し安定性を保ち、導入時のリスクを最小限に抑えるために行われます。

テストの実施によって欠陥を早期に発見でき、欠陥の修正にかかるコスト発生の回避やソフトウェア品質の向上につながります。

 ソフトウェアテストは次のテストレベルが一般的に定義されています(図表1、2)。

図表1:テストレベルのイメージ
図表1:テストレベルのイメージ

テストレベル

概要

単体テスト(Unit Test)※1

個々の関数や小さなコンポーネント単位での動作を確認する

結合テスト(Integration Test)※2

各コンポーネント間の相互作用を確認する

システムテスト(System Test)

全てのコンポーネントを統合した後、システム全体として正しく機能するかを確認する

受け入れテスト(Acceptance Test)

システムがユーザーの要求を満たし、運用が可能な状態であることを確認する

図表2:テストレベルごとの概要

※1 JSTQBではコンポーネントテスト(ユニットテスト)と表記されますが、本文章ではこれ以降「単体テスト」と表現します。
※2 JSTQBでは(コンポーネント)統合テストと表記されますが、本文章ではこれ以降「結合テスト」と表現します。 

ソフトウェア開発の後工程で欠陥が発見された場合、修正コストが大幅に増加するため、単体テストと結合テストを適切に実施することは特に重要です。

単体テストと結合テストによって欠陥を早期に発見することで、手戻りによる修正費用を削減し、開発期間を短縮すると共に、製品の信頼性を高めることができます。

単体テストと結合テストの定義

単体テストと結合テストの定義の違いを以下に解説します。

単体テスト(Unit Test)とは

単体テストは、ソフトウェアの各独立した単位(関数、クラス、コンポーネントなど、使用するプログラミング言語によって異なる)でテストすることにより、コンポーネントに対する詳細設計仕様通りに正しく動作することを確認するテストレベルです。

単体テストでは、コンポーネント間の相互作用を検証するのではなく、テスト対象となるコンポーネントの内部ロジックに着目したテストを行います。 

結合テスト (Integration Test)とは

結合テストは、複数のコンポーネントを組み合わせて動作させ、それらが統合後に設計仕様通りに機能することを確認するテストレベルです。

単体テストと結合テストの目的の違い

単体テストと結合テストの目的の違いを解説します。

単体テストの目的

単体テストの目的は、ソースコードの正確性のテスト(関数/コンポーネントが詳細設計仕様通り、または正しいロジックで動作しているか)、リファクタリングの支援(ソースコードの変更や新機能の追加を行った際に、単体テストによって既存機能が正しく動作し続けることを保証)、詳細設計仕様の補完(テストケースそのものがコンポーネントの動作仕様を示す資料となり、他の開発者が機能を理解しやすくするため)です。

結合テストの目的

結合テストでは、各コンポーネントが正しく連携して動作することを確認します。具体的には、データの受け渡し、関数呼び出し、API通信、データベース操作などが正確であることをテストします。 

こういった行為により、コンポーネント間の通信に関する欠陥を早期に検出します。 

また、連携するコンポーネントを統合する際に、正しいデータフローおよびインターフェースでの通信が行われていることも確認します。

単体テストと結合テストのアプローチの違い

単体テストと結合テストのアプローチとそれぞれの違いを解説します。

単体テストのアプローチ

単体テストには、一般的に次の二つのアプローチがあります(図表3)。

  • テスト・ラスト開発(Test-Last Development:TLD)
  • テスト駆動開発(Test-Driven Development:TDD)
図表3:TLDとTDDのイメージ
図表3:TLDとTDDのイメージ

TLD (Test-Last Development :テスト・ラスト開発)

ソースコードの実装が完了した後にテストケースを作成するという、従来型のアプローチです。項目ごとにまとめると以下のようになります(図表4)。

項目 

内容 

特徴

テスト担当者または開発者が、完成済みのコンポーネントを検証するためにテスト(テスト用のコードやテストケース)を作成する。主な目的は、コーディング後に欠陥を検出し、ソースコードが詳細設計仕様を満たしているかを確認すること。

利点

既存プロジェクトやレガシーシステムに適用しやすい。
実行時エラーやロジックエラーを、ソースコードが安定稼働した段階で検出できる。 

欠点

テストが既存コードに依存するため、高いテストカバレッジは確保しにくい。また、開発の早期段階における設計上や論理上の欠陥を見逃しやすい。欠陥の検出が遅れる傾向があるため、修正コストが高くなり、リファクタリングも複雑になりやすい。

適用するケース

・ウォーターフォール モデルやV字モデルなど、工程が順次進行する従来型開発モデルに適用する場合。
・レガシー コードやメンテナンスプロジェクトを扱う場合。
・最初にテストを書く習慣がない場合。

図表4:TLDの特徴

TDD (Test-Driven Development:テスト駆動開発) 

ソースコードを実装する前にテストを作成する開発手法です(図表5)。 

図表5:TDDのイメージ
図表5:TDDのイメージ

プロセスがRed – Green – Refactor サイクルに基づきます。

Red

Green

Refactor

最初にテストを作成し、テストが失敗することを確認(まだソースコードがないため)

テストを成功させるために、最小限のソースコードを実装

コードをリファクタリングし、全てのテストが成功することを確認

項目ごとにまとめると以下のようになります(図表6)。

項目

内容

特徴

テストの観点からコード設計を導くことができ、システムの各小単位が厳密にコントロールされる。

利点

テスト駆動の方針によりコード品質を向上させる。コンポーネント化された設計とテストの併存により、保守性・拡張性が高い。

欠点

開発初期段階で時間と工数を要する。開発者に高いテストスキルが求められる。

適用するケース

新規プロジェクト、アジャイル環境、あるいはコードの安定性とリファクタリング可能性を向上したい場合。

図表6:TDDの特徴

TLD(テスト・ラスト開発)は、シンプルなプロセス構造、明確な開発工程、および初期段階における変更要求の少なさから、従来型ソフトウェア開発モデルに適し、比較的実施しやすいでしょう。

一方で、ソースコードの保守性、安定性、詳細設計に対する網羅性といった観点では、TDD(テスト駆動開発)の方が明確な優位性を持ちます。プログラミング前にテストを記述することにより、開発者は詳細設計仕様をより深く理解し、早期に欠陥を検知して修正コストを低減できます。

また、プロジェクト全体を通してソースコード品質を維持できます。加えて、TDDはシステムの拡張性や将来的な変更への適応性を高める効果もあります。 

関連記事:テスト駆動開発(TDD)とは?やり方からメリット・デメリットまで解説

結合テストのアプローチ方法

結合テストのアプローチ方法は主に以下の二つです。

  • ビッグバンテスト(Big-Bang Integration)
  • インクリメンタル統合(Incremental Integration)

ビッグバンテスト(Big-Bang Integration)

ビッグバンテストでは全てのモジュールを統合してから結合テストを行います(図表7、8)。

図表7:ビッグバンテストのイメージ
図表7:ビッグバンテストのイメージ

項目

内容

利点

計画が立てやすく、テストを一度に実施可能。
処理をつなげたテストを一度で賄えるため工数削減できる。

欠点

テスト失敗時に、どのコンポーネントが原因であるか特定することが困難。
欠陥の発見が遅れ、修正に時間を要する可能性が高い。

適用するケース

コンポーネント数が少なく、仕様変更が少ない、小規模システムの場合のみ。

図表8:ビッグバンテストの特徴

インクリメンタル統合(Incremental Integration)

インクリメンタル統合にはトップダウン統合(Top-Down Integration)と、ボトムアップ統合(Bottom-Up Integration)があります。

トップダウン統合(Top-Down Integration)では、上位コンポーネントから下位コンポーネントへ順にテストを行います。 下位コンポーネントがまだ利用可能でない場合は、スタブ(stub)を使用します(図表9、10)。

図表9:トップダウン統合のイメージ
図表9:トップダウン統合のイメージ

項目

内容

利点

処理フロー(ロジック)の欠陥を早期に検出し、システム全体の一連の機能を確認できる。

欠点

スタブ作成が必要になり、 下位コンポーネントのテストが後回しになりやすい。

適用に適するケース

全体的なロジックフローを先に確認したい場合に適用。

図表10:トップダウン統合の特徴

ボトムアップ統合(Bottom-Up Integration)では、下位コンポーネントから上位コンポーネントへ順にテストを行います。上位コンポーネントがまだ利用可能でない場合は、ドライバ(driver)を使用します(図表11、12)。

図表11:ボトムアップ統合のイメージ
図表11:ボトムアップ統合のイメージ

項目

内容

利点

基盤となるコンポーネントの欠陥を早期に検出でき、個々のコンポーネントをテストしやすい。

欠点

全体としての機能確認が遅れる傾向にある。また、ドライバ作成が必要。

適用するケース

基盤となるコンポーネントの安定性を事前に確認したい場合。

図表12:ボトムアップ統合の特徴

単体テストと結合テストを実施するタイミング

単体テストは開発者が個別のコンポーネント、関数、またはクラスを開発した直後に実施します。通常、コーディング工程中、かつ各コンポーネント統合前に行われます。

一方、結合テストは各コンポーネントの単体テストが終わった統合後に行います。

ソフトウェア開発モデルにおける単体テスト・結合テストの順番

ウォーターフォール(Waterfall)モデルでは、テスト工程は開発工程が完了した後に実施されます。

このため、単体テストが最初に行われます。単体テストが完了したら結合テストに移り、システムテスト、受け入れテストの順となります(図表13)。

図表13:ウォーターフォールモデルのイメージ
図表13:ウォーターフォールモデルのイメージ

V字モデルはウォーターフォールを変形し、V字の左側の各工程は右側のテストレベルにより妥当性確認を行うことを示したものです。

各テストレベルはウォーターフォールに基づき、開発工程が完了した後で、単体テスト→ 結合テスト → システムテスト → 受け入れテストの順で行われます(図表14)。

図表14:V字モデルのイメージ
図表14:V字モデルのイメージ

関連記事:V字モデルとは?特徴やメリット・デメリットを解説

アジャイル開発モデルは、ウォーターフォールが示すシーケンシャル型モデルとは異なり、柔軟で反復的かつ漸進的(iterative & incremental)な開発モデルです。

アジャイルモデルでは、要件分析 → 設計 → コーディング → テスト → リリースという一連の工程を順番に行うのではなく、プロジェクト全体を複数の短い反復(イテレーション、SCRUMではスプリント)に分割します。各反復では、開発チームが製品の(動作可能な小さな機能単位)に対して、分析・設計・実装・テスト・納品といった一連の活動を全て行います。これにより、早期にフィードバックを得て、次の反復で柔軟に調整できます。

各反復で、単体テスト(UT)・結合テスト(IT)・システムテスト(ST)・受け入れテスト(AT)といった各種テストは順次ではなく、並行かつ重なる形で実施します。一つの小機能が完成し次第、すぐにテストが行われるため、早期のフィードバックが得られ、継続的な品質確保と反復終盤での統合リスクの低減につながります。

以下の図表15は、アジャイル開発において、反復(SCRUMの単位だとスプリント)を複数回行いながらプロダクトリリースを行うイメージを示しています。

図表15:アジャイル開発のイメージ
図表15:アジャイル開発のイメージ

 関連記事:アジャイルテストとは?4象限の内容や実践手順を解説 

さらにテストの流れがイメージしやすくなるように、例を挙げて解説します。

コンポーネント A、Bの単体テストを実装した後に、すぐにITを実施します。そして、コンポーネントCの実装とUTが完了したら、三つのコンポーネントのITを行って、STとATも実施します。

こうしてアジャイル開発におけるテストでは、基本的に一つのコンポーネントに対してテストの順番がUT→IT→ST→ATで変わりませんが、一つのテストレベルが完了してから次のテストレベルに移動するのではなく、各テストレベルは重なる形で実行できます。

  • UT: 一つのコンポーネント/機能が完了したら、スプリント内に行う
  • IT: グループのコンポーネント/機能が完了した後に実行し、継続的に統合し、統合テストを行う

まとめると、モデルごとのテストレベルは基本的に以下の順序に従います。

UT → IT → ST → AT

  1. UT: 最も下位のレベルで、個々のユニットを確認する
  2. IT: 中間レベルで、各ユニット・コンポーネント間のインタラクションを確認する
  3. ST、AT:上位レベルで、システム全体の動作や、ユーザー要件を確認する

単体テストと結合テストのプロセスの違い

以下の表にて、単体テストと結合テストを実施するステップを示した上で、各ステップで単体テストと結合テストの違いを示します(図表16)。

ステップ

単体テスト(UT)

結合テスト(IT)

目標の定義

  • 個別コンポーネントの確認 
  • コンポーネント内ロジックの正確性保証
  • コンポーネント間の連携の確認
  • コンポーネントのUIとデータフローの正確性保証

テスト範囲の定義

  • 関数・クラス・コンポーネント単位で確認
  • 必要なスタブ/モック以外のコンポーネントを考慮しない

 

  • 複数のコンポーネントで確認
  • 統合戦略(ビッグバン方式、増分方式、トップダウン方式、ボトムアップ方式)を定義
  • 重要な業務やデータフローを特定

テスト技法の選択

  • 通常、ロジック、分岐、境界条件をテストするためにホワイトボックステストを適用
  • コンポーネントのアウトプットのみ確認する場合、ブラックボックステストも適用可能
  • 通常、全体的な機能を確認するためにブラックボックステストを適用
  • コンポーネント間のデータフローを確認するために、ロジックを理解する必要がある場合、グレーボックステストも適用可能

データと環境の準備

  • 環境/フレームワーク: コンポーネントテスト用ツールやテストハーネス
  • テストコード:スタブ(stub)、モック(mock)、フェイク(fake)など
  • 異なる境界条件と入力条件を用意
  • テストカバレッジ測定の準備
  • 環境/フレームワーク: DB、API、サービス、ブラウザー、デバイス、ビルド版などや統合テスト用ツール類
  • 業務フローを反映する実際のデータ、または実データに近いデータ
  • テストカバレッジ測定の準備

詳細なテストケースの設計

  • 単体テスト仕様作成:コンポーネント単位のインプット、期待結果、実施ステップ
  • テスト仕様に基づいてテストコード/テストスクリプトを作成
  • 結合テスト仕様作成:コンポーネント間のインプット/アウトプット、期待結果、実施ステップ
  • テスト仕様書に基づいてテストスクリプトを作成

テスト実行と結果分析

  • テストコード/テストスクリプトを実行
  • 各コンポーネントのテスト結果(合格/失敗、ロジックエラー、例外)を分析
  • テストスクリプトを実行
  • データフロー、コンポーネント間の連携、発見バグなどテスト結果を分析

テスト結果と関連資料のまとめ

  • 各テストケース、問題、コードカバレッジ、テストケースの結果、ログを記録
  • テスト結果と発見した欠陥のレポートを作成
  • 各テストケース、問題、依存関係、テストケースの結果、ログを記録
  • テスト結果と発見した欠陥のレポートを作成

図表16:単体テストと結合テストのプロセス

単体テストと結合テストを適切に行って品質を向上させよう

単体テストはコンポーネント単位の品質保証とバグの早期発見により開発効率を高め、結合テストはコンポーネント間の連携やシステム全体の動作確認を行います。両者を適切に組み合わせることでソフトウェアの信頼性が向上します。

単体テストや結合テストは、システム品質を支える基本的な工程ですが、実務に落とし込むにはノウハウや実行力が不可欠だと言えます。

■参照■

SNSシェア

この記事は面白かったですか?

今後の改善の参考にさせていただきます!

Search Articles By The Cast出演者/執筆者から記事を探す

Search Articless By The Categoryカテゴリから記事を探す

Ranking

ランキング

もっと見る