テストの種類・単体テストと結合テストとシステムテスト

2020年9月2日テスト品質

開発フェーズに沿ったテストの名前

単体テスト結合テストシステムテストとはソフトの開発フェーズに沿って付けられたテストの名前なのですが、皆さんはどのように定義していますか? グータラ親父の使っていた定義は以下のような物です。

  • 単体テスト:ソースコードの機能単体での動作確認とパスの網羅確認
  • 結合テスト:複数の機能モジュールでの相互動作の確認
  • システムテスト:全機能の安定性や堅牢性などを主体に確認

テストの名前として一番よく聞く単体テスト結合テストシステムテスト なのですが、実は組織によってその定義が微妙に異なっている事があるので注意が必要です。一般的なので使いやすい名前なのですが、テストの時期担当者目的、テストの方法、テスト結果の利用方法などの項目に注意して、テストの定義を確認しておくと間違いは少なくなります。

この記事では、グータラ親父が使っていた定義を参考に紹介していますが、これが正解という訳では無くこのような定義もあるのだなと思って読んで下さい。

単体テストはモジュール単体での網羅テスト

単体テストは、コーディングの直後に行います。テストを実施するのはコーダ自身で、テストの目的はソースコードが詳細設計のとおりに動作する事の確認です。ソフトの詳細設計では、機能や関数を最小の単位として、①提供する機能 ②インプットに対する処理とアウトプット ③検出するエラーとそのエラーに対する処理 ④想定外のエラーに対する処理方針、などを具体的に決めていきます。コーディングでは、これらの詳細設計の内容を実際のソースコードに書き下していく事になります。

ですので、単体テストでは詳細設計で決めた内容がソースコードに記述されていて、詳細設計で決められたとおりにコードが動作する事を逐一確認していきます。

単体テストの方法はおおきく分けると2つに分けられます。1つ目は、モジュールや関数などに様々な入力や内部状態を与えて、それに対して結果やエラーリターンの値が設計どおりに出力される事を確認する方法です。ソースコードの中身を知った上で、入力に対して設計通りの出力がえられるかを確認するテスト方法なので、グレーボックステストと呼ばれる事もあります。

2つ目の方法は、モジュールや関数に様々な入力や内部状態を与える所まで1つ目とは同じですが、それらに対してソースコードが設計したとおりに実行されるのかをステップバイステップで1行毎に追いかけていく方法です。 ソースコードの中身を知った上でそのソースコードが設計したとおりに実行される事を確認するテストの方法なので、ホワイトボックステストとも呼ばれます。

ソースコードの実行をステップ倍ステップで確認していくテストは、パステストとも呼ばれます。コードの実行される道=パスを確認するテストという意味ですね。パステストを使う場合には、記述したコードの全てのパスを確認をしたかという、パステストの網羅率をテスト実施の目標に使う事もよくあります。全てのパスをテストした網羅率100%が理想ですが、テスト条件やソフトの規模によっては網羅率100%は達成が難しいので、網羅率80%を目標にする、という事もあります。網羅率を使う時には、命令網羅か分岐網羅か条件網羅か、網羅率の定義にも注意が必要ですので、同値分割と境界値分析とパス網羅の記事の記事も合わせて読まれる事をお勧めします。

単体テストはコード作成直後の初期デバッグと一体化して実施される事が多いのと、テストはコーダ自身が実施するる場合が多いので、テストで見つかったバグはそのままコーダがデバッグしていきます。 バグの発見者とコードの修正者が同じならば、バグの再現条件や再現手順は別に記録が無くとも問題ないので、単体テストで見つかったバグについては通常のバグ管理を行わない事もよくあります。 バグ管理の目的が、効率的なデバッグによるソフトの品質改善なので、バグの検出がそのままデバッグ作業に直結している単体テストでは、バグ管理をしなくても問題無いという考え方も十分に説得力はあります。

結合テストは複数モジュールの連携機能のテスト

結合テストは、単体テストの次に実施されるテストですが、開発規模が小さい時にはシステムテストに含めてしまう事もあります。テストを実施するのは、コーダ自身の場合もあれば設計部門内の結合テスト担当者の場合もあります。このへんは、プロジェクトの規模によりまちまちですね。

結合テストの目的は、複数の機能の間の協調動作の確認です、単体テストでは個々のモジュール単位での動作を確認しているので、ここでは複数のモジュール間での動作の連携で実現される機能が、基本設計どおりに動作していう事を確認します。結合テストでは、正常系や異常系や準正常系の様々な入力を与えて、それらの入力に対して設計どおりの動作をするのか、というブラックボックステストが基本です。

テストの方法もまたその開発プロジェクトによって様々になります。 ただ、様々な入力を与えて動作をみるブラックボックステストの方法をとりながらモジュール間の動作の連携を確認するには、本来そのソフトが持つインタフェースだけではテストが実施し難い場合も多いです。 ですので、結合テストの場合には、テストを実施する事を目的としたテストアプリテストスーツを本来のソフトとは別に作成して、これらを使ってテストをする場合が多いです。また、時ににはテスト専横のスタブを作成して様々なエラーをわざと発生させて、準正常系や異常系のテストを進める事もあります。もちろんん、ソフトが本来持っている様々なつインタフェースを使って結合テストを進める場合もあります。

単体テストで機能の単独の動作確認が十分に済んでいれば、結合テストではモジュール間の連携機能の確認に集中する事ができます。複数のモジュールが連携すす場合には、なんらかのモジュール間インタフェース、例えば共有メモリ経由だったり、メッセージ通信だったり、リモート呼び出しだったり、を使って複数のモジュールが連携する仕組みが作られています。結合エストでは、これらのモジュール間インターフェースに焦点をあてて、インターフェースを介して正常な情報が交換されている場合、設計されたエラー情報が交換されている場合、設計に無い異常状態が発生している場合、などに分けて連携機能のテストを行っていきます。

組み込み系システム連携機能を確認するの結合テストでは、タイムアウト処理の確認がシステムの信頼性や堅牢性の確認という視点から大切ですので、このテストを忘れないようにします。機能連携をする場合、その機能が同じ計算機の内部にある場合でも他の計算機の上にある場合でも、連携している相手が常に正しく動作してくれているとは限りません。連携する相手が何等かの事情で、例えばバグだったり動作環境の異常とかで、正しく動作できない場合に自分の処理をハングアップさせないための仕組みとしてタイムアウト処理が組まれています。このタイムアウト処理が正しく動作する事を確認するのは、結合テストの大きな目的の1つです。

結合テストでは、テストを実施は複数の設計・実装者が手分けして実施したり専門の結合テスト担当者が実施したりと、開発組織によっていろいろです。 しかし、コーダ自身がテストをしない場合が多いので、テストで見つけたバグを正しく管理する事が必要になります。そのため、結合テストで見つけたバグはなんらかのバグ管理システムに情報を記録して、再現やその後のバグの修正などの管理を行うのが一般的です。