このセクションでは、C++test を使って 単体テスト ケースを自動生成する方法について説明します。テスト ケースを利用して、回帰テストのための機能スナップショットをキャプチャーできます。また、例外を引き起こす条件を特定することもできます。例外の発生は、不安定なシステムやアプリケーション、セキュリティ脆弱性 (サービスの拒否攻撃など)、パフォーマンスの低下、アプリケーションのレスポンス時間、頻繁なダウンタイムといった問題を引き起こすことがあります。
このセクションの内容 :
テスト ケースの自動生成
C++test は、テスト コンフィギュレーションの [生成] タブで定義されたパラメーターに従ってテスト ケースを自動生成します。自動生成テスト ケースの形式は、CppUnit 形式に似ています。
新しい機能を検証するためのテスト生成
新しいコードの機能を検証したい場合、まず関数ごとに 1 - 2 個のテストを自動生成することを推奨します。
テストを自動生成して実行した後に、ユーザー定義テスト ケースを追加してテスト スイートを拡張できます。詳細については 「テスト スイートの拡張と変更」を参照してください。
回帰テスト用のテストの生成
コードの現在の動作をキャプチャした回帰テスト ベースラインを作成したい場合 (たとえば確実にコードの動作が正しいことがわかっている場合) には、[ビルトイン] > [Unit Testing] > [Generate Regression Base] テスト コンフィギュレーションを使用します。このテスト コンフィギュレーションを実行すると、C++test は自動的にすべてのテスト結果を正しい結果として検証済みにします。
これらのテストを定期的に (たとえば 24 時間ごとに) 自動的に実行すれば、回帰テストでキャプチャした関数にコードの変更が影響を与えていないかどうかを検証できます。テスト結果が変わった場合、テスト ケースは失敗となり、問題があることを開発チームに知らせます。
今後のテストにおいて、最初のテストでキャプチャした動作と異なる動作が検出された場合、C++test はタスクをレポートします。
デフォルトの設定では、C++test は 1 つのファイルにつき 1 つのテスト スイートを生成します。設定を変更すれば、1 つの関数につき 1 つのテスト スイートを生成することもできます。 (「生成オプションのカスタマイズ」 を参照してください。)
C++test は「セーフ(安全な)スタブ定義」を自動生成して危険な関数を置き換えます。セーフ スタブ定義は、ほとんどのシステム I/O ルーチン (rmdir()、remove()、rename() など) について使用できます。また、C++test は見つからない関数定義と変数定義のためのスタブも自動生成できます (「スタブの自動生成とカスタマイズ」を参照)。ユーザー定義スタブは必要に応じて追加できます ( 「スタブの追加と変更」を参照)。
生成の手順
テスト ケースを生成するための全般的な操作手順は次のとおりです。
- テスト ケースを生成するテスト コンフィギュレーションを選択または作成します。
- C++test のビルトイン テスト コンフィギュレーションの詳細については 「ビルトイン テスト コンフィギュレーション 」を参照してください。
- ユーザー定義テスト コンフィギュレーションの作成方法については「テストコンフィギュレーションとルールの設定」を参照してください。C++test に固有のテスト コンフィギュレーション オプションについては 「Configuring Test Configurations and Rules 」 を参照してください。
- テストを実行します。
GUI からのテスト方法については「GUI からのテスト」を参照してください。
コマンドラインからのテスト方法については 「コマンドライン インターフェイスからのテスト 」を参照してください。ヒント - [テスト ケース エクスプローラー] ビューからのテスト生成
[テスト ケース エクスプローラー] ビューから直接テストを生成することができます (このビューを表示するには、[Parasoft] > [ビューの表示] > [テスト ケース エクスプローラー] をクリックします)。[テスト ケース エクスプローラー] ビューでプロジェクト ノードを選択して右クリックし、ショートカット メニューの からテスト生成用のテスト コンフィギュレーションを実行します。
テスト ケース エクスプローラーの詳細については「GUI の概要」を参照してください。
- 生成されたテスト ケースをレビューします。
- 詳細については 「自動生成テスト ケース」を参照してください。
- (オプション) 必要に応じてテスト生成の設定を調整します。
- 詳細については 「[生成] タブ - テスト ケースの生成方法を定義する」を参照してください。
生成オプションのカスタマイズ
テスト コンフィギュレーションの [生成] タブでは、さまざまな生成オプションをカスタマイズできます。
テスト スイートのファイル名、場所、レイアウトの制御
テスト スイートのファイル名、場所、粒度、およびレイアウトは、テスト コンフィギュレーションの [生成] > [テスト スイート] タブで制御できます。
デフォルトのテスト スイート出力設定を変更するには、まず [テスト スイート出力ファイルとレイアウト] から次のいずれかの定義済みオプションを選択します。
- テスト対象関数ごとにテスト スイートを生成
- テスト対象ソース/ヘッダー ファイルごとにテスト スイートを生成
- テスト対象ソース ファイルごとにテスト スイートを生成
[テスト対象関数ごとにテスト スイートを生成] を選択した場合、このテスト コンフィギュレーションを使って ATM サンプル プロジェクトをテストすると、次のようなテスト スイートが生成されます ( ATM プロジェクトは C++test のインストール ディレクトリの Examples/ATM ディレクトリにあります)。
- ${test_ext} - C++test 固有のテスト スイート ファイルの拡張子 (.cpp)
- ${file_name} - ファイル名
- ${file_base_name} -拡張子なしのファイル名
- ${file_ext} - ファイルの拡張子
- ${file_loc} - ファイルの場所
- ${file_loc_rel} - ファイルの場所 (プロジェクト ルートからの相対の場所)
- ${file_uid} - ファイルの一意な識別子
- ${function_name} - テスト対象の関数名
- ${function_uid} - テスト対象関数の一意な識別子 (関数のシグニチャ/マングル名からハッシュ コード計算された識別子)
- ${src_file_name} - コンテキスト (ソース) ファイルの名前 (「コンテキスト ファイル」とは、テスト対象関数が定義されているコンパイル単位を記述したソース ファイルのこと)
- ${src_file_base_name} - 拡張子なしのコンテキスト (ソース) ファイルの名前
- ${src_file_ext} - コンテキスト (ソース) ファイルの拡張子
- ${src_file_loc} - コンテキスト (ソース) ファイルの場所
- ${src_file_loc_rel} -コンテキスト (ソース) ファイルの場所 (プロジェクト ルートからの相対パス)
- ${src_file_uid} - コンテキスト (ソース) ファイルの一意な識別子 (ソース ファイルの場所からハッシュ コード計算された識別子)
キー
- file = テスト対象関数が定義されているソース/ヘッダー ファイル
- src file = テスト対象関数が定義されているコンパイル単位を定義するソース ファイル
変数を削除することによって、テスト スイートのオーバーラップが起こることがあります。その場合、C++test は「テスト スイート出力ファイル パターンがあいまいです」というエラー メッセージを表示して警告します。
C++test は、生成されたテストの場所についての基本パターンの変更に関連する、次の内部チェックと制限を行います。
- すべての自動生成テストは "インクルード" タイプです 。テスト スイート ファイルはソース ファイル/コンパイル単位によってまとめられます。
- C++test は、異なるコンパイル単位の関数に対するテスト ケースが同じテスト スイート ファイル中に置かれることを防ごうとします (なぜなら、そのようなテスト スイート ファイルをオリジナル ソース ファイルとまとめることは不可能だからです)。
- C++test は、テスト スイート ファイル パターンを (テスト対象のファイル、その名前、および場所などに関して) 明確に表すために使用できる、異なる変数を持ちます (これらの変数は、テスト対象のファイル、その名前、および場所などに基づいて解決されます)。
- よく使用される手法の 1 つとして、オリジナル ファイル/場所があるファイル/場所にテスト スイート ファイルを生成する方法があります。デフォルト パターンは次のとおりです。
${project_loc}/tests/autogenerated/${file_loc_rel}/
TestSuite_${file_base_name}_${file_ext}.${test_ext}
これは、あいまいではありません。なぜなら、${file_loc_rel} および ${file_base_name} 変数が使用されるからです (たとえプロジェクト中に同名のファイルが数多くあったとしても、そのファイルの場所は異なります。そして、その場所がテスト スイート ファイルの名前/場所の一部になります)。
- 利用できる変数は他にもあります。たとえば、${file_loc_rel} と ${file_base_name} の代わりに、パターンを明確にする ${file_uid} と${src_file_uid} を使用できます。${file_uid} と${src_file_uid} は、オリジナル ファイルの場所のハッシュ コードに解決されます。たとえば次のパターンからは
${project_loc}/tests/autogenerated/
TestSuite_${file_base_name}_${file_uid}_${file_ext}.${test_ext}
次のテスト スイートが生成されます。
ATM/tests/autogenerated/TestSuite_Account_d7a5efc6_hxx.cpp
既存テストの追加と置き換え
既存のテスト ケースがある場合に、新しいテスト ケースで既存のテスト スイートを置き換えるか、それとも新しいテスト ケースを既存のテスト スイートに統合するかを指定できます。テスト コンフィギュレーションの [生成] > [テスト スイート] タブの [テスト ケースの生成 (既存のテストスイートを使用)] で、次のいずれかのオプションを選択します。
- テスト ケースがない関数に対してテスト ケースを追加する テスト ケースがない関数についてテスト ケースを生成します。既存のテストへの影響や変更はありません。
- すべての関数に対してテスト ケースを追加する すべての関数についてテスト ケースを生成します。既存のテストへの影響や変更はありません。
- 既存のテスト スイートを置き換える すべての関数についてテスト ケースを生成します。既存のテスト スイートは削除されて新しいテスト ケースで置き換えられます。
C++test は、既存のテスト ケースがあるかどうかをどのように判定するのか ?
C++test は、テスト スイート ファイル中の CPPTEST_CONTEXT および CPPTEST_TEST_SUITE_INCLUDED_TO マーカーを探します。
一般的なテスト生成の目的
以下の表では、一般的なテスト生成の目的を達成するためにテスト コンフィギュレーションの生成オプションをどのように設定するかについて説明します。[生成] > [全般] タブの [テスト生成のパターン] および [生成] > [テスト スイート] タブの [テスト ケースの生成 (既存のテストスイートを使用)] について説明します。
目的目的 | 設定 |
テストの初期セットを生成する | [テスト生成のパターン] で [テスト スイートが存在しない場合にテスト コードを生成する] チェックボックスをオンにします。 他のパラメーター (関数アクセス レベル、出力ファイルの場所と名前など) を指定します。 |
新しい関数のテストを使って、既存の自動生成テスト スイートを更新する (新しいテスト スイートは生成しない) | [テスト生成のパターン] で [テスト対象のファイルが更新された場合にテスト ケースを生成する] および [テスト対象のファイルが更新されていない場合にテスト ケースを生成する] チェックボックスをオンにします。 [テスト ケースの生成 (既存のテストスイートを使用)] で [テスト ケースがない関数に対してテスト ケースを追加する] を選択します。 他のパラメーター (関数アクセス レベル、出力ファイルの場所と名前など) を指定します。 |
自動生成テスト ケースと現行コードの同期を取る (欠けているテストを追加し、欠けているテスト スイートを作成する) | [テスト生成のパターン] で [テスト スイートが存在しない場合にテスト コードを生成する]、[テスト対象のファイルが更新された場合にテスト ケースを生成する]、および [テスト対象のファイルが更新されていない場合にテスト ケースを生成する] チェックボックスをオンにします。 [テスト ケースの生成 (既存のテストスイートを使用)] で [テスト ケースがない関数に対してテスト ケースを追加する] を選択します。 他のパラメーター (関数アクセス レベル、出力ファイルの場所と名前など) を指定します。 |
既存の自動生成テストを完全にリセットする | [テスト生成のパターン] で [テスト スイートが存在しない場合にテスト コードを生成する]、[テスト対象のファイルが更新された場合にテスト ケースを生成する]、および [テスト対象のファイルが更新されていない場合にテスト ケースを生成する] チェックボックスをオンにします。 [テスト ケースの生成 (既存のテストスイートを使用)] で [既存のテスト スイートを置き換える] を選択します。 他のパラメーター (関数アクセス レベル、出力ファイルの場所と名前など) を指定します。 |
注意
C++test はオリジナルのプロジェクトの場所にすべての自動生成テストを保管します。ソリューション エクスプローラーに似た適切なディレクトリ構造が自動的に作成されます。ルートはプロジェクトの場所です。
目的に合ったレイアウト オプションの選択
このセクションでは、[テスト スイート出力ファイルとレイアウト] オプションの設定方法について説明します。このオプションは、テスト コンフィギュレーションの [生成] > [テスト スイート] タブにあります。各オプションがプロジェクトで実際にどのように解釈されるかをわかりやすくするために、次のサンプル プロジェクトを使って、各オプションの影響について説明します。
MyProject Header Files MyClass.h // contains foo() definition Source Files MyClass.cpp // contains bar() and goo() definitions
1 つの関数につき 1 つのテスト スイートを生成し、別のディレクトリにテストを置く
Use ${project_loc}/tests/${file_loc_rel}/${file_name}/
TestSuite_${function_name}.${test_ext}
レイアウトの例:
MyProject Header Files MyClass.h Source Files MyClass.cpp tests Header Files MyClass.h TestSuite_foo.cpp // contains tests for foo() Source Files MyClass.cpp TestSuite_bar.cpp // contains tests for bar() TestSuite_goo.cpp // contains tests for goo()
ソース/ヘッダー ファイルごとに 1 つのテスト スイートを生成し、別のディレクトリにテストを置く
${project_loc}/tests/${file_loc_rel}/
TestSuite_${file_base_name}_${file_ext}.${test_ext}
レイアウトの例:
MyProject Header Files MyClass.h sSource Files MyClass.cpp tests Header Files TestSuite_MyClass_h.cpp // contains tests for foo() Source Files TestSuite_MyClass_cpp.cpp // contains tests for bar() and goo()
ソース/ヘッダー ファイルごとに 1 つのテスト スイートを生成し、テスト対象ファイルと同じ場所にテストを置く
${project_loc}/${file_loc_rel}/tests/
TestSuite_${file_base_name}_${file_ext}.${test_ext}
レイアウトの例:
Header Files MyClass.h tests TestSuite_MyClass_h.cpp // contains tests for foo() Source Files MyClass.cpp tests TestSuite_MyClass_cpp.cpp // contains tests for bar() and goo()