このセクションでは、テスト中にアクセスできないリソースのためにユーザー定義スタブを使用する方法と、自動生成スタブを変更する方法について説明します。スタブの概要および開発時にどのようにスタブが役立つかについては「スタブ」を参照してください。
このセクションの内容
|
[スタブ] ビューは、最後に実行した単体テスト コンフィギュレーションに基づいてスタブ コンフィギュレーションの詳細を表示します。[スタブ] ビューでは、見つからないシンボルに対してユーザー定義スタブまたは自動生成スタブを作成して、スタブ コンフィギュレーションを変更することができます。
[Parasoft] メニューの [ビューの表示] > [スタブ] をクリックします。
[スタブ] ビューを初めて表示したときは、ビューは空です。「シンボル データが収集されませんでした」というメッセージが表示されます。 |
[スタブ] ビューには以下の列を持つテーブルが表示されます。
[スタブ] ビューの内容は、単体テスト中に収集されたデータに基づいて更新されます。またユーザー スタブの作成や自動スタブの作成などの [スタブ] ビューから実行できる特定のアクションの結果として更新されます。[スタブ] ビューの内容は、手動でのスタブの追加または削除などの外部のアクションによっては更新されないことに注意してください。
[スタブ] ビューには、最後に使用されたスタブの設定に関する情報とともに、他の利用可能だが使用されなかった定義の情報も表示されます。たとえば、ユーザー スタブが定義されている関数の場合、既存のオリジナルの定義も表示されます。このような未使用の定義の [定義] 列には、"(未使用)"
と表示されます (例: "Original (not used)"
)。 未使用の定義を非表示にするには、[スタブ] ビューのツール バーの [フィルター] ボタンをクリックし、[使用されていない定義を非表示] をオンにします。
1 つの関数に 2 つ以上のスタブ定義がある場合 (たとえば、特定の関数に対して 2 つのユーザー スタブ定義がある場合など)、[スタブ] ビューに複数の定義が表示されます。スタブ アイコンの上にエラーを表すマークが付けられ、[定義] 列に "(コンフリクト)"
と表示されます (例: "User
(conflict
)")。
シンボル データを収集またはリフレッシュするには、次の操作を行います。
スタブ ビューでは、自動生成スタブが保存される場所を指定できるほか、動的スタブ設定の任意のモードを有効または無効にできます (「動的スタブの設定」を参照)。
ウィザードでスタブ ファイルを生成し、それを編集することによってユーザー定義スタブを追加するには、次の操作を行います。
スタブのディレクトリはプロジェクト内のどこにあってもかまいません。デフォルトでは、C/C++test はプロジェクトの stubs サブディレクトリにスタブがあると仮定します。しかし、テスト コンフィギュレーション設定画面の [実行] > [シンボル] タブの [次の場所で発見されたファイルのシンボルも使用] フィールドでスタブの場所を変更すれば、デフォルトとは異なる場所を使用することができます。
プロジェクト ディレクトリ内にスタブを保存しない場合、ファイル システムの他の場所にあるファイルとリンクするフォルダーを追加できます。次の操作を行います。 a. [ファイル] メニューの [新規] > [フォルダー] をクリックします (このメニュー項目がない場合、[ファイル] メニューの [新規] > [その他] をクリックし、[一般] の [フォルダー] を選択して [次へ] ボタンをクリックします)。 b. [拡張] ボタンをクリックします。 c. [ファイル システム内のフォルダーにリンク] チェックボックスをオンにします。 d. リンクするファイルの場所を入力します。 e. [終了] をクリックします。 |
プロジェクト ツリーでスタブのディレクトリを選択し、 右クリックしてショート カット メニューの [新規] > [その他] をクリックします。ウィザードが表示されます。[C++test] > [ユーザー スタブ] を選択し、[次へ] をクリックします。ウィザードの関数テーブルでスタブを作成する関数を選択し、[次へ] をクリックします。
|
#include
ディレクティブが自動的に追加されます。#include
ディレクティブを確認し、必要に応じて変更します。特定のライブラリのすべての関数に対してスタブを素早く作成する場合、テーブルを場所でソートすると、ライブラリのすべての関数を選択するのが容易になります。 |
空のスタブ ファイルにユーザー定義スタブを追加するには、次の操作を行います。
プロジェクト ツリーでスタブのディレクトリを選択し、右クリックしてショート カット メニューの [新規] > [その他] をクリックします。ウィザードが表示されます。[C++test] > [ユーザー スタブ] を選択し、[次へ] をクリックします。 ウィザードの関数テーブルでスタブを作成する関数を選択し、[次へ] をクリックします。
stub とタイプしてスタブのテンプレートを作成し、"stub" の "b" の直後にカーソルを置いて Ctrl+ Space キーを押し、適切なテンプレートを選択します。テンプレートにはC または C++ 関数の標準スタブ テンプレートまたはコンストラクター/デストラクター テンプレートがあります。
Tab キーを使用して ret_type、scope、name、parameters の間を移動できます。 |
8.スタブのボディ (定義) を入力します。「ユーザー定義スタブのための C/C++test API 関数」で説明されているように、ユーザー定義スタブは C/C++test API 関数とやり取りできます。
9.変更したファイルを保存します。
次の操作を行って、テスト コンフィギュレーションの関数スタブ モードが [プロジェクト外部のシンボルにもスタブを使用する] に設定されていることを確認します。
|
仮想関数をスタブ化する場合、ポインターまたは参照がコンパイル時に指すクラスの関数に対して必ずスタブを作成してください。たとえば次のコードでは、(*) でマークされた呼び出しは、Base::doSth() 関数のスタブが作成される場合にだけスタブ化されます。
ポインターによって指し示すオブジェクトの実際の実行時の型は関係ありません。 |
演算子のユーザー定義スタブを作成するには、次のスタブ関数名を使用します。
演算子 | 関数名 |
---|---|
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 関数」 を参照)。
スタブまたはスタブ テンプレートをカスタマイズするには、次の操作を行います。
コンストラクター スタブを除く C++test のスタブはオリジナルの関数と同じ値を受け取ることに注意してください。
セーフ スタブ定義は、「危険な関数」を置き換えるために自動生成されます。セーフ スタブ定義は、ほとんどのシステム I/O ルーチン (rmdir()
、remove()
、rename()
など) について使用できます。セーフ スタブ定義を使用した場合、たとえオリジナル関数があってもオリジナル関数は呼び出されません。利用できる場合はセーフ スタブ定義を使用することを推奨します。セーフ スタブ定義を使用すると、単体テスト中に発生する問題を防止できます。ただし、セーフ スタブ定義をユーザーが変更することはできません。
自動生成されたセーフ スタブ定義を使用しない場合は、テスト コンフィギュレーションでセーフ スタブ定義を無効化します。[実行] タブの [シンボル] タブの [次の場所で発見されたファイルのシンボルも使用] フィールドから ${cpptest:cfg_dir}/safestubs
エントリを削除します。
特定の関数についてセーフ スタブの使用を無効化してオリジナル定義を使用するには、オリジナル関数の呼び出しのラッパーとして機能するユーザー定義スタブを作成します。例:
int CppTest_Stub_mkdir(const char* p) { return mkdir(p); } |
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); } |
「コンパイラとリンカーのオプション設定」で説明されているとおり、ユーザー定義スタブ ファイルごとに、カスタム コンパイラ オプションを設定できます。