このセクションでは、テスト中にアクセスできないリソースのためにユーザー定義スタブを使用する方法と、自動生成スタブを変更する方法について説明します。スタブの概要および開発時にどのようにスタブが役立つかについては「スタブ」を参照してください。
このセクションの内容
注意
- スタブを使用する場合は、テスト コンフィギュレーションの [実行] > [全般] タブで [インストゥルメント モード] 設定を [完全]、[カバレッジ計測なし (スタブあり)]、スタブ インストゥルメントを含むカスタム インストゥルメントのいずれかに必ず設定してください。
- C/C++test では、スタブの優先順位が次の順序で定められています。 ユーザー定義スタブ、自動生成セーフ スタブ、オリジナル関数、自動スタブしたがって、自動生成スタブが使用されるのは、他の定義 (ユーザー定義スタブまたはオリジナル関数) が使用できない場合だけです。
- C/C++test は、コードまたはライブラリ中にオリジナルの定義がある場合、デストラクターをスタブ化しません。デストラクターの C++test 生成スタブが使用されるのは、オリジナルのデストラクターが使用できない場合だけです。
[スタブ] ビューでのスタブの参照
[スタブ] ビューは、最後に実行した単体テスト コンフィギュレーションに基づいてスタブ コンフィギュレーションの詳細を表示します。[スタブ] ビューでは、見つからないシンボルに対してユーザー定義スタブまたは自動生成スタブを作成して、スタブ コンフィギュレーションを変更することができます。
[スタブ] ビューへのアクセス
[Parasoft] メニューの [ビューの表示] > [スタブ] をクリックします。
初回のスタブ ビュー オープン時
[スタブ] ビューを初めて表示したときは、ビューは空です。「シンボル データが収集されませんでした」というメッセージが表示されます。
[スタブ] ビューについて
[スタブ] ビューには以下の列を持つテーブルが表示されます。
- シンボル: 関数またはグローバル変数の名前です。
- 定義: 現在の定義 (スタブ) の種類です。
- ユーザー: ユーザーが作成した定義 (スタブ) が使用されます。
- セーフ: C++test のセーフ定義 (スタブ) が使用されます。
- オリジナル: オリジナルの定義が使用されます。
- 自動: C++test の自動定義 (スタブ) が使用されます。
- なし (不要): 定義はありません。リンカーは定義を必要としません。
- なし: 定義はありませんが、リンカーは定義を必要としています。多くの場合、この状態はテスト実行可能ファイルをビルドした場合にリンカー エラーを引き起こします。
- 場所: 現在の定義 (ソース ファイル、ライブラリ) の場所です。見つからない場合は N/A です。
[スタブ] ビューの更新
[スタブ] ビューの内容は、単体テスト中に収集されたデータに基づいて更新されます。またユーザー スタブの作成や自動スタブの作成などの [スタブ] ビューから実行できる特定のアクションの結果として更新されます。[スタブ] ビューの内容は、手動でのスタブの追加または削除などの外部のアクションによっては更新されないことに注意してください。
未使用の定義
[スタブ] ビューには、最後に使用されたスタブの設定に関する情報とともに、他の利用可能だが使用されなかった定義の情報も表示されます。たとえば、ユーザー スタブが定義されている関数の場合、既存のオリジナルの定義も表示されます。このような未使用の定義の [定義] 列には、"(未使用)"
と表示されます (例: "Original (not used)"
)。 未使用の定義を非表示にするには、[スタブ] ビューのツール バーの [フィルター] ボタンをクリックし、[使用されていない定義を非表示] をオンにします。
複数の定義
1 つの関数に 2 つ以上のスタブ定義がある場合 (たとえば、特定の関数に対して 2 つのユーザー スタブ定義がある場合など)、[スタブ] ビューに複数の定義が表示されます。スタブ アイコンの上にエラーを表すマークが付けられ、[定義] 列に "(コンフリクト)"
と表示されます (例: "User
(conflict
)")。
シンボル データの収集とリフレッシュ
シンボル データを収集またはリフレッシュするには、次の操作を行います。
- プロジェクト ツリーでテスト対象のファイルを選択します。
- テスト実行可能ファイルをビルドするテスト コンフィギュレーション (たとえば Collect Stub Information または Build Test Executable など) を実行します。
スタブ ビューでのスタブ オプションの設定
スタブ ビューでは、自動生成スタブが保存される場所を指定できるほか、動的スタブ設定の任意のモードを有効または無効にできます (「動的スタブの設定」を参照)。
- スタブビューのメニューに移動し、[スタブ設定...] をクリックして設定ダイアログを開きます。
- [自動生成スタブ出力先] フィールドに自動生成スタブが保存される場所を指定します。
- 動的スタブ設定の以下のモードを有効または無効にします。
- スタブ コールバックの有効化 - 有効な場合、動的スタブの設定にスタブ コールバック メカニズムが使用されます。デフォルトで有効です (詳細は「スタブ コールバックの使用」を参照)。このオプションはデフォルトでオンです。
オリジナルの関数への呼び出しを挿入 - 有効な場合、生成されたスタブはオリジナルの関数を呼び出します。「オリジナルの関数を呼び出すスタブの作成」を参照してください。このオプションはデフォルトでオフです。 - スタブ API の有効化 (非推奨) - 有効な場合、動的スタブの設定にスタブ API が使用されます (詳細は「動的スタブの設定」を参照)。このオプションはデフォルトでオフです。
- スタブ コールバックの有効化 - 有効な場合、動的スタブの設定にスタブ コールバック メカニズムが使用されます。デフォルトで有効です (詳細は「スタブ コールバックの使用」を参照)。このオプションはデフォルトでオンです。
[スタブ] ビューの使用のヒント
- コード エディターでシンボル定義 (スタブ) の箇所に移動するには、対応するテーブルの行をダブルクリックします。または、行を右クリックしてショートカット メニューの [移動] をクリックします。このメニューは、定義が含まれるファイルが現在のプロジェクトの一部である場合にだけ利用できます。
- スタブ定義が含まれるファイルを削除するには、テーブルでファイルを選択し、ショートカット メニューの [スタブ ファイルを削除] をクリックします。ファイルに含まれるすべてのスタブ定義が削除されます。
- テーブルを列の値でソートするには、列のヘッダーをクリックします。
- テーブルの内容を検索するには、テーブルを右クリックしてショートカット メニューの [検索] をクリックし、検索条件を指定します。
ウィザードによって生成されたスタブ ファイルへのユーザー定義スタブの追加
ウィザードでスタブ ファイルを生成し、それを編集することによってユーザー定義スタブを追加するには、次の操作を行います。
- 新しいスタブのディレクトリを作成します (まだこの操作を行っていない場合)。
スタブのディレクトリはプロジェクト内のどこにあってもかまいません。デフォルトでは、C/C++test はプロジェクトの stubs サブディレクトリにスタブがあると仮定します。しかし、テスト コンフィギュレーション設定画面の [実行] > [シンボル] タブの [次の場所で発見されたファイルのシンボルも使用] フィールドでスタブの場所を変更すれば、デフォルトとは異なる場所を使用することができます。
- 次のいずれかの方法でスタブ ウィザードを開きます。
- [スタブ] ビューでスタブを作成する関数を右クリックし、[ユーザー スタブを作成] をクリックします。
プロジェクト ツリーでスタブのディレクトリを選択し、 [C++test] > [ウィザード] > [新規ユーザー スタブ ファイルの作成] を選択します。ウィザードが表示されます。ウィザードの関数テーブルでスタブを作成する関数を選択し、[次へ] をクリックします。
注意
- 「シンボル データが収集されませんでした」という警告は、必要なシンボル データがまだ収集されていないことを表しています。シンボル データの収集/更新の詳細については 「シンボル データの収集とリフレッシュ」を参照してください。
- 「スタブを作成するシンボルがありません」という警告は、ユーザー定義スタブを作成できる関数がないことを表しています。
- [カスタム スタブ ウィザード] ダイアログで新規スタブ ファイルの名前と場所を入力します。
- [終了] をクリックします。ユーザー定義スタブ ファイルが作成され、コード エディターで開かれます。ファイルには適切な定義と必要な
#include
ディレクティブが自動的に追加されます。 - スタブの定義や
#include
ディレクティブを確認し、必要に応じて変更します。 - 変更したファイルを保存します。
ユーザー定義スタブに関する追加情報
- 複数の関数のスタブを 1 度に作成できます。テーブルで複数の関数を選択し、選択を右クリックして [ユーザー スタブを作成] ショートカット メニューをクリックします。すべてのユーザー定義スタブが同じスタブ ファイルに追加されます。
- 任意の関数のスタブを作成できます。
- ユーザー定義スタブの優先度は最高です。オリジナルの定義が利用可能な場合でも、ユーザー定義スタブが使用されます。
- グローバル変数に対しては作成できません。代わりに自動スタブを使用するべきです。
特定のライブラリのすべての関数に対してスタブを素早く作成する場合、テーブルを場所でソートすると、ライブラリのすべての関数を選択するのが容易になります。
空のスタブ ファイルへのユーザー定義スタブの追加
空のスタブ ファイルにユーザー定義スタブを追加するには、次の操作を行います。
- 次のいずれかの方法でスタブ ウィザードを開きます。
- [スタブ] ビューでスタブを作成する関数を右クリックし、[ユーザー スタブを作成] をクリックします。
プロジェクト ツリーでスタブのディレクトリを選択し、[C++test] > [ウィザード] > [新規ユーザー スタブ ファイルの作成] を選択します。ウィザードが表示されます。 ウィザードの関数テーブルでスタブを作成する関数を選択し、[次へ] をクリックします。
- 空のスタブ ファイルを作成するため、関数テーブルでは関数を選択しません。
- [次] をクリックします。
- スタブ ファイルの名前と場所を入力します。
- [終了] をクリックします。スタブ ファイルが自動的にエディターで開かれます。
stub とタイプしてスタブのテンプレートを作成し、"stub" の "b" の直後にカーソルを置いて Ctrl+ Space キーを押し、適切なテンプレートを選択します。テンプレートにはC または C++ 関数の標準スタブ テンプレートまたはコンストラクター/デストラクター テンプレートがあります。
スタブを追加する場所で右クリックし、[Parasoft] > [C++test] > [スニペットの挿入] > [<テンプレート タイプ>] (C または C++ 関数用の標準スタブ テンプレートまたはコンストラクター/デストラクター スタブ テンプレート)をクリックしてスタブ テンプレートを作成します。- ret_type、scope、name、parameters の箇所に適切な値を挿入します。コンストラクター スタブを除く C/C++test のスタブはオリジナルの関数と同じ値を受け取ることに注意してください。
8.スタブのボディ (定義) を入力します。「ユーザー定義スタブのための C/C++test API 関数」で説明されているように、ユーザー定義スタブは C/C++test API 関数とやり取りできます。
9.変更したファイルを保存します。
演算子のユーザー定義スタブを作成するには、次のスタブ関数名を使用します。
演算子 | 関数名 |
---|---|
new | CppTest_Stub_operator_new |
delete | CppTest_Stub_operator_delete |
new[] | CppTest_Stub_operator_array_new |
delete[] | CppTest_Stub_operator_array_delete |
+ | CppTest_Stub_operator_plus |
- | CppTest_Stub_operator_minus |
* | CppTest_Stub_operator_star |
/ | CppTest_Stub_operator_divide |
% | CppTest_Stub_operator_remainder |
^ | CppTest_Stub_operator_excl_or |
& | CppTest_Stub_operator_ampersand |
| | CppTest_Stub_operator_or |
~ | CppTest_Stub_operator_or |
! | CppTest_Stub_operator_not |
= | CppTest_Stub_operator_assign |
< | CppTest_Stub_operator_lt |
> | CppTest_Stub_operator_gt |
+= | CppTest_Stub_operator_plus_assign |
-= | CppTest_Stub_operator_minus_assign |
*= | CppTest_Stub_operator_times_assign |
/= | CppTest_Stub_operator_divide_assign |
%= | CppTest_Stub_operator_remainder_assign |
^= | CppTest_Stub_operator_excl_or_assign |
&= | CppTest_Stub_operator_and_assign |
|= | CppTest_Stub_operator_or_assign |
<< | CppTest_Stub_operator_shift_left |
>> | CppTest_Stub_operator_shift_right |
>>= | CppTest_Stub_operator_shift_right_assign |
<<= | CppTest_Stub_operator_shift_left_assign |
== | CppTest_Stub_operator_eq |
!= | CppTest_Stub_operator_ne |
<= | CppTest_Stub_operator_le |
>= | CppTest_Stub_operator_ge |
&& | CppTest_Stub_operator_and_and |
|| | CppTest_Stub_operator_or_or |
++ | CppTest_Stub_operator_plus_plus |
-- | CppTest_Stub_operator_minus_minus |
->* | CppTest_Stub_operator_arrow_star |
-> | CppTest_Stub_operator_arrow |
() | CppTest_Stub_operator_function_call |
[] | CppTest_Stub_operator_subscript |
<? | CppTest_Stub_operator_gnu_min |
>? | CppTest_Stub_operator_gnu_max |
, | CppTest_Stub_operator_comma |
定義のないシンボルのスタブを生成する
[スタブ] ビューのテーブルで関数を右クリックし、ショートカット メニューの [自動スタブを作成] をクリックします。自動スタブ ファイルが作成され、エディターで開かれます。ファイルには適切な定義と必要な #include ディレクティブが自動的に追加されます。
複数の関数のスタブを 1 度に作成できます。
- テーブルで複数の関数を選択して選択を右クリックします。
- [自動スタブを作成] ショートカット メニューをクリックします。すべての自動スタブが同じスタブ ファイルに追加されます。
利用可能な定義がないシンボルに対してだけ作成できます。その他のシンボルに対してはユーザー定義スタブを代わりに使用します。
自動スタブの優先度は最低です。他に利用可能な定義がある場合は、自動スタブは使用されません。
自動生成スタブのカスタマイズ
C/C++test では、見つからない関数定義のためのスタブを自動生成できます。
自動生成スタブはユーザー定義スタブと同じ機能を持ちます。ただし、接頭辞は異なります。ユーザー定義スタブの接頭辞は CppTest_Stub_
であり、自動生成スタブの接頭辞は CppTest_Auto_Stub_
です。このため、ユーザーはスコープ中の 1 つの関数に複数のスタブを用意できます。
完全なスタブ定義を自動生成できない場合は、スタブ テンプレートが作成され、ユーザーは return 文を入力したりインクルード ディレクティブを追加したりしてカスタマイズできます。スタブ テンプレートはファイル内の完全なスタブの前に保存されます。
自動生成スタブは、他にユーザー スタブもオリジナル スタブもない場合にだけ使用されます。
動的スタブ API から、またはテスト ケース エディターのスタブ ステップ を使って、自動生成スタブを簡単に構成することができます (「動的スタブの設定」 および 「ステップの設定」 を参照)。
まれなケースとして、動的スタブ API やテスト ケース エディターでは不十分な場合、生成されたスタブの本体を、CppTest_IsCurrentTestCase
スタブ関数などのカスタム ロジック実装で完全に置き換えることができます ( 「ユーザー定義スタブのための C/C++test API 関数」 を参照)。
スタブまたはスタブ テンプレートをカスタマイズするには、次の操作を行います。
- タブ ファイルを開きます。スタブ ファイルは、テスト コンフィギュレーションの [実行] > [シンボル] タブの [自動生成スタブ出力先] で設定された場所に保存されています。
- ret_type、スコープ、名前、パラメーターを変更します。
コンストラクター スタブを除く C++test のスタブはオリジナルの関数と同じ値を受け取ることに注意してください。
- 必要に応じてスタブの本体/定義を変更します。「ユーザー定義スタブのための C/C++test API 関数」で説明されているように、ユーザー定義スタブは C++test API 関数とやり取りできます。
- 変更後のファイルを保存し、解析を再度実行します。
自動生成されたセーフ スタブ定義の無効化
セーフ スタブ定義は、「危険な関数」を置き換えるために自動生成されます。セーフ スタブ定義は、ほとんどのシステム I/O ルーチン (rmdir()
、remove()
、rename()
など) について使用できます。セーフ スタブ定義を使用した場合、たとえオリジナル関数があってもオリジナル関数は呼び出されません。利用できる場合はセーフ スタブ定義を使用することを推奨します。セーフ スタブ定義を使用すると、単体テスト中に発生する問題を防止できます。ただし、セーフ スタブ定義をユーザーが変更することはできません。
自動生成されたセーフ スタブ定義を使用しない場合は、テスト コンフィギュレーションでセーフ スタブ定義を無効化します。[実行] タブの [シンボル] タブの [次の場所で発見されたファイルのシンボルも使用] フィールドから ${cpptest:cfg_dir}/safestubs
エントリを削除します。
特定の関数についてセーフ スタブの使用を無効化してオリジナル定義を使用するには、オリジナル関数の呼び出しのラッパーとして機能するユーザー定義スタブを作成します。例:
int CppTest_Stub_mkdir(const char* p) { return mkdir(p); }
ユーザー定義スタブのための C/C++test API 関数
void CppTest_Assert(bool test, const char * message)
この関数は標準の assert 関数と同じように動作します。test パラメーターの値が失敗するたびにテスト ケースの実行が停止されます。その場合、テスト ケースの結果として「ユーザー定義のアサーションが失敗した」という内容のメッセージがレポートされます。さらに、message パラメーターの値、場所、およびスタック トレースの情報が詳細情報として表示されます。
void CppTest_Break()
この関数を使うと、無条件でテスト ケースの実行を停止できます。「ユーザー定義のブレークが呼び出された」という内容のメッセージが表示されるほか、場所とスタック トレース情報が表示されます。
bool CppTest_IsCurrentTestCase(const char* id;
現在実行されているテスト ケースを問い合わせることができます。現在実行されているテスト ケース名に testCaseName が一致する場合、この関数は true
を返します。 一致しない場合、false
を返します。この機能は、外部関数の呼び出しに基づいた条件文を使用する関数に役立ちます。例については 「テスト ケースから呼び出されるスタブ用の関数」 を参照してください。
bool CPPTEST_DS_HAS_COLUMN(const char* name)
この関数を使用すると、ユーザー定義スタブと自動スタブのデータ ソース列をクエリーできます。データ ソースはテスト ケース固有であるため、特定のテスト ケースの文脈でスタブが呼び出される場合にだけデータを利用できることに注意してください (グローバルな初期化中などにスタブが呼び出された場合、データを利用することはできません) 。
const char* CppTest_GetCurrentTestCaseName(); const char* CppTest_GetCurrentTestSuiteName();
現在実行されているテスト ケース/テスト スイートの名前を取得します。特定のテスト スイートの特定のテスト ケースに適用するスタブを作成できます。
例については 「テスト ケースから呼び出されるスタブ用の関数」 を参照してください。
スタブでのデータ ソースの使用
C/C++test で使用するために設定した任意のデータ ソースをスタブで使用できます。
データ ソースを設定するには、「データ ソースの追加」で説明されている操作を行います。
スタブでデータ ソースを使用するには、ブール型の CPPTEST_DS_HAS_COLUMN(const char* name) API 関数を使用します。次のようにしてデータ ソースの列をクエリーできます。
int CppTest_Stub_goo (void) { if (CPPTEST_DS_HAS_COLUMN("stub_goo_return")) { return CPPTEST_DS_GET_INTEGER("stub_goo_return"); } else { return 0; // Data Source not available } }
データ ソースはテスト ケース固有であるため、特定のテスト ケースの文脈でスタブが呼び出される場合にだけデータを利用できることに注意してください (グローバルな初期化中などにスタブが呼び出された場合、データを利用することはできません) 。
bool CPPTEST_DS_HAS_COLUMN(const char* name)
マクロは、CppTest_isCurrentTestCase() などの他の API 関数と組み合わせて使用できます。
コンテキストごとに異なるテスト/スタブを使用する
「異なるコンテキストでの異なるテスト/スタブの使用」を参照してください。
動的スタブ設定の使用
「動的スタブの設定」を参照してください。
テスト ケースから起動されるスタブ
C/C++test では、現在実行されているテスト ケースから起動できるユーザー定義スタブを作成できます。C/C++test API には次の関数があります。
bool CppTest_IsCurrentTestCase(const char* id);
この関数を「ユーザー スタブ」定義で使用すると、現在実行されているテスト ケースを確認できます。現在実行されているテスト ケース名に id が一致する場合、この関数は true
を返します。 一致しない場合、false
を返します。
この機能は、外部関数の呼び出しに基づいた条件文を使用する関数に役立ちます。例:
void foo() { if (goo() == 1) { //code } else { //code } }
100% の行カバレッジを得るために、ユーザーは foo()
関数に対して 2 つのテスト ケースを作成し、次に goo()
関数に対して 1 つのユーザー スタブを作成できます。
int ::CppTest_Stub_goo() { if (CppTest_IsCurrentTestCase("TestCase1")) { return 1; } else { return 0; } }
このスタブはテスト ケースによって起動できます。この例では、現在実行されているテスト ケース が TestCase1
かどうかによって戻り値が変わります。現在実行されているのが TestCase1
の場合、戻り値は 1 であり、それ以外の場合、戻り値は 0 です。この処理によって、foo()
関数のカバレッジを 100% 取得できます。
テスト ケースによるスタブ ドライバーの作成に役立つ API 関数として、 const char* CppTest_GetCurrentTestCaseName();
および const char* CppTest_GetCurrentTestSuiteName(); があります。現在実行されているテスト ケース/テスト スイートの名前を取得します。特定のテスト スイートの特定のテスト ケースに適用するスタブを作成できます。たとえば次のスタブは、AllocTestSuite テスト スイートのテスト ケースで名前に nomemoryを含むすべてのテスト ケースについて、異なった振る舞いをします。
#include <string> #include <stdlib.h> EXTERN_C_LINKAGE void* CppTest_Stub_malloc(size_t size) { std::string testSuiteName = CppTest_GetCurrentTestSuiteName(); std::string testCaseName = CppTest_GetCurrentTestCaseName(); if ((testSuiteName == "AllocTestSuite") && (testCaseName.find("nomemory") != std::string::npos)) { // Simulate no memory situation. return 0; } return malloc(size); }
ユーザー定義スタブ ファイルのためのカスタム コンパイラ オプション
「コンパイラとリンカーのオプション設定」で説明されているとおり、ユーザー定義スタブ ファイルごとに、カスタム コンパイラ オプションを設定できます。