単体テストと結合テストの違いについて【UTのテスト観点あり】

2023年6月8日

みなさんこんにちは。はるまきです。今回は「単体テストと結合テストの違いについて」ご紹介します。

テストの分類方法

まずはそもそものテストの分類について軽く紹介します。

システム開発にはさまざまなテスト方法が存在します。

そしてそれらは次の3つの方法で分類できます。何に着目するかによって分けています。

  • 「ソフトウェアの内部構造に注目するかどうか」 による分類
  • 「ソフトウェアを動作させるかどうか」 による分類
  • ソフトウェア開発の工程による分類

これらで分類したときにどのように分けられるかを一つずつ見ます。

「ソフトウェアの内部構造に注目するかどうか」 による分類

1つ目のこの分類ではテストは「ホワイトボックステスト」と「ブラックボックステスト」に分けられます。

ホワイトボックステストはプログラムの構造に注目して実施されるテストです。分岐とかデータ処理が正しく行われているかを確認します。

一方、ブラックボックステストはプログラムの内部構造は意識せずに単に入力と出力のみに注目してテストします。黒い箱は中身が見えないのでこういう呼び方なんだと思います。

「ソフトウェアを動作させるかどうか」 による分類

2つ目のこの分類ではテストは「静的テスト」と「動的テスト」に分けられます。

静的テストは動かして動作確認をしません。つまり、プログラムのソースを目で見て、「あ、これだとバグりそうだな」的な感じで判断するテストですね。レビューとかがこれになります。設計工程でも設計書を読んだだけでバグを検知できれば、それは静的テストをしたことになります。

一方で動的テストとは、実際にプログラムを動かして動作確認をすることです。画面をぽちぽちしてみたり、作成したプログラムを実行して処理が正常かどうかなどを検証することです。

ソフトウェア開発の工程による分類

最後のこの分類方法は、システム開発の工程に注目しています。よくV字開発とかいいますよね。そのテスト工程のことです。テストは大きく以下のように分けれます。

  • 単体テスト
  • 結合テスト
  • システムテスト

よくV字開発の図とかで出てきますよね。アレです。

単体テスト→ 結合テスト → システムテスト の順番でテストをしていくのが一般的です。

この、単体テストと結合テストの境界線はどこにあるの? を本記事では明確にしていきます。

3つの分類の方法があることを知った上で、少し整理をしたいです。単体テストと結合テストの違いを明確にする前に、それらがどこに位置するのかを整理します。

  1. システム開発にはテストが何種類もある。
  2. その上で、3つの分類の仕方がある
  3. 「単体テスト」と「結合テスト」という概念が生まれるのは、テストを「工程による分類」をしたとき

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

本記事のメインです。結論から言うと、

「単体テストはプログラムの内部構造に注目し、結合テストはプログラムの内部構造は完全無視してモジュール(機能)を合体させて(外から)テストする」って感じですかね。

ホワイトボックスとブラックボックスという分類でキッパリ分かれます。単体テストはホワイトボックスで、結合テストはブラックボックスです。

では実際に単体テストと結合テストではどういうことをテストするのかを説明します。

単体テストのテストケースを考える

単体テストはモジュールごとに行います。1つの関数ごとにテストするイメージでも大丈夫です。

ここにある関数を用意しました。その人が成人で収入が多いかどうかを判定する関数です。なんでもいいんですが。

function isRich(age, income) { // age 年齢, income 年収
  if (age >= 18) {
    console.log('成人')
    if (age >= 40 && income >= 2000) {
      console.log('ダンディでお金持ち!')
    }
  }
}

この関数を単体テストしてみましょう。

テストケース作成の前にどれくらい網羅したいかを考える

単体テストに限った話ではないですが、理想は網羅率100%のテストを実施することです。ですが現実的には工数の問題で網羅率100%を継続することは難しいです。例えば上記のisRich関数であれば、age(年齢)やincome(年収)がマイナスのときとか、ageは42でダンディなんだけど、incomeが300のケースとか。などなど。

細かいところまでカバーしようとすると工数がかかってしまいます。

そこで、どれくらい網羅したいのかを考えます。

単体テストでは、

  • ステートメントカバレッジ
  • デシジョンカバレッジ
  • 複合条件カバレッジ

という3つのカバレッジ基準(網羅したいレベル)があります。

1つずつご紹介します。

ステートメントカバレッジとは?

ステートメントカバレッジは、「全ての命令文を最低一度は通すように実行する」 という網羅レベルです。

ここでいう命令文とは分岐文ではなく、console.logなどの処理のことです。つまり、フローチャート上でいう「"成人"を出力」と「"ダンディでお金持ち!"を出力」のところが命令文です。これを最低一度を通るようにテストすれば、ステートメントカバレッジ基準だとOKになります。

よってここでは、1つのテストケースで完了することになります。つまり、age:42歳, income:2500 のようなデータを用意して実行し、無事に「成人」と「ダンディでお金持ち!」が出力されてればOKです。

ただこれだけではなんだか心配ですね。age:16の時どうなん? とかです。

次のデシジョンカバレッジを紹介します。

デシジョンカバレッジとは?

デシジョンカバレッジとは、分岐した経路に着目したカバレッジ基準です。分岐する経路を見るんですね。フローチャートでいうと、以下のようになります。

画像が下手ですみません。ブルーの線が(先ほどのステートメントカバレッジの線も含めて)、3本になりました。

  • 分岐がすべてyesのパターン
  • 18歳以上か? で noのパターン
  • 40歳以上且つ2000以上か? で noのパターン

の3ケースです。

この3ケースをテストすれば、デシジョンカバレッジ基準としてはクリアです。テストケースは全部で3つで済みます。

ただこれでも不安は残ります。

  • 40歳でincomeが300の時は?
  • 30歳でincomeが2500の時は?

などです。このパターンをも網羅しようと言うのが複合条件カバレッジになります。

複合条件カバレッジとは?

複合条件カバレッジでは、分岐の「条件」に注目します。ここでは、分岐の条件が、以下です。

  • 18歳以上か?
  • 40歳以上 且つ 年収2000万円以上か?

これに注目して、組み合わせを考えます。すると以下のようになります。

このように条件に注目して、あらゆるパターンを組み合わせの方法で網羅していくのが複合条件カバレッジの考え方です。これがもっとも網羅率の高い基準になります。

ここまで見たように、カバレッジ基準には3つあります。

  • ステートメントカバレッジ
  • デシジョンカバレッジ
  • 複合条件カバレッジ

網羅率は上記で見てきたように、

ステートメントカバレッジ < デシジョンカバレッジ < 複合条件カバレッジ

のようになります。

特徴として、大きな方を実施すればそれよりも小さいカバレッジ基準のテストをしなくても自然にカバーできていることになります。つまり、複合条件カバレッジでテストを実施すればステートメントカバレッジ、デシジョンカバレッジは実施しなくてもカバーできてますし、デシジョンカバレッジでテストをすればステートメントカバレッジは実施しなくてもカバーできてます。

結局単体テストのテストケースとは?

上記で見てきたように、単体テストのテストケースは採用するカバレッジ基準によって変わります。ですが、その根底にあるのは、プログラムの内部構造に注目しテストする。ということです。ロジックの1つ1つを何かしらの基準をもってテストできれば問題ないです。逆に言うと単体テストのテスト範囲は、そこに限定するべきです。

もっと単体テストと結合テストの違いについて知りたい方、またはソフトウェアのテストをもっと学習したい方はこちらの本が入門書としてはおすすめです。

まとめ

まとめです。今回は単体テストのやりかたに注目しながら、単体テストと結合テストの違いについて、明確にしました。少しでも役に立てたら幸いです。