このセクションでは、テストに事前定義または自動生成されたデータ ソースの値を使用する方法について説明します。さまざまなデータ ソース セットに対してテストを実行することによって、テスト量とカバレッジを容易に増加させることができます。

このセクションの内容

スタブでのデータ ソースの使用

C/C++test で使用するために設定した任意のデータ ソースをスタブで使用できます。詳細については 「スタブでのデータ ソースの使用」を参照してください。

データソースの追加

データ ソースは GUI ウィザードから定義することができます。ウィザードを使って、カンマ区切り (.csv) ファイル、Excel シート (.xls)、データベース クエリー、および C++test で定義されたデータ ソース テーブルのデータを指定することができます。テスト ケースの実行中、指定したデータ ソースがテスト ケースによって使用されます。

C++test で定義されたデータ ソースは、プロジェクト レベルまたは 1 つのテスト スイート レベルで [テスト ケース エクスプローラー] ビューから定義することができます。プロジェクト レベルで定義したデータ ソースはプロジェクト中のすべてのテスト スイートで利用できます。テスト スイート レベルで定義したデータ ソースは、そのテスト スイートでしか利用できません。さらに、C++test で定義されるデータ ソースはワークスペースレベルで作成できます。

プロジェクト/テスト スイート レベルで既存データ ソースを追加する

プロジェクト/テスト スイート レベルで C++test で定義されたデータ ソースを作成するには、次の操作を行います。

  1. [テスト ケース エクスプローラー] ビューでプロジェクトまたはテスト スイートのノードを選択します。
  2. 選択したノードを右クリックし、ショートカット メニューの [新規追加] > [データ ソース] をクリックします。
  3. データ ソースの種類を選択します。




  4. 表示された画面でデータ ソースを設定します。 たとえば .csv ファイルへのパスやデータ ソース パラメーター、SQL クエリーなどです。

 JDBC ドライバーの指定

データベースに接続するには JDBC ドライバーが必要です。C++test には Oracle および MySQL 用にビルトイン ドライバーが用意されています。ビルトイン ドライバーを置き換えたり外部ドライバーを追加するには、[Parasoft] メニューの [設定] > [JDBC ドライバー] でドライバーを追加します。

ワークスペース レベルで既存データ ソースを追加する


C++test で定義されるデータ ソースを ワークスペース レベルで作成するには、次の操作を行います。

  1. [テスト ケース エクスプローラー] ビューで [グローバル データ ソース] ノードを右クリックし、ショートカット メニューの [新規追加] > [データ ソース] をクリックします。



  2. データ ソースの種類を選択してデータ ソースを定義します。

新規データ ソースの自動生成

自動生成のデータ ソース値を使って、カンマ区切り (.csv) ファイルまたは C++test で定義されたテーブル データ ソースを生成することができます。

テスト ケース エディターで自動的に新規データ ソースを生成する方法については、「テスト ケース エディターで追加されたテスト ケースをデータ ソースでパラメータライズする」を参照してください。

テスト ケース ウィザードでテスト ケースを設定するには、次の操作を行います。

  1. テスト ケース ウィザードのエディター ページでテスト ケースを設定中に [自動生成] ボタンをクリックします。
  2. 表示された [自動生成] ダイアログでデータ ソースの設定を行います。


データ ソースを生成する際、C++test は編集可能な値を持つ事前条件と事後条件ごとにデータ ソース列を作成します。編集可能な値は、論理型、整数型、浮動小数点型、および文字列型です。データ ソースはテスト スイート レベルで生成されます。

生成したデータ ソースは、同じテスト スイート中の他のテスト ケースをパラメータライズするために使用できます。

データ ソース値によるテスト ケースのパラメータライゼーション

テスト ケース エディターで作成されたテスト ケースをデータ ソースでパラメータライズする 

テスト ケース エディターで作成したテスト ケース (「テスト ケース エディターによるテスト スイートとテスト ケースの追加」を参照) をデータ ソースの値を使用してパラメータライズできます。テスト ケースに埋め込まれたデータ ソース テーブルまたは外部データ ソースの値を使用できます。

  1. テスト ケース エクスプローラーを開いてテスト スイートを右クリックします。
  2. [新規追加] > [エディターを使用したテスト ケース] を選択します。
  3. [次のテスト ケースを作成] ドロップダウン リストから関数を選択します。
  4. [新規パラメータライズド テスト ケースを作成] ボタン () をクリックしてデータ ソース選択ダイアログを開きます。
  5. 使用するデータソースを選択します。以下のオプションがあります。
    ビルトイン テーブル - テスト ケースにパラメータライズ値を指定するためのテーブルが追加されます (ビルトイン テーブルで指定した値にアクセスするために使用できる パラメーター API については「Adding Test Case Parameterization」を参照)。
    外部データ ソース - パラメータライズ値を指定するための外部データ ソースを自動生成します。カンマ区切り値 (.csv) ファイルまたはテーブル データ ソースを生成できます。 このオプションを選択した場合、[自動生成] ウィンドウで任意の設定を指定し、[OK] をクリックします。データ ソースはテスト スイート レベルで生成されます。

         
  6. テスト ケースを保存してテスト スイートに追加します。

テスト ケース ウィザードで作成されたテスト ケースをデータ ソースでパラメータライズする

データ ソース値を使って、テスト ケース ウィザードでテスト ケースを作成するときにテスト ケースの値を定義するだけでなく、既存のテスト ケース (自動生成またはユーザー定義) をパラメータライズすることもできます。データ ソースの値は、上記で説明した C++test で定義されたデータ ソースであれば、どのデータ ソースからも取得することができます。

注意

データ ソース値を使って入力をパラメータライズしたテスト ケースの場合、C++test は未検証の結果およびアサーションの失敗を自動検証できません。 その理由は、入力がパラメータライズされている場合、C++test は通常、データ ソース値を使ってパラメータライズされた「期待される結果」を必要とするからです。

テスト ケース ウィザードからデータ ソースの使用を設定する

C++test で定義したデータ ソースから値を取得するテスト ケースをテスト ケース ウィザードで新規作成することができます。

  1. テスト ケース エクスプローラーで、テスト スイート ノードを右クリックして [新規追加] > [ウィザードを使ったテスト ケース] をクリックします。
  2. ウィザードの最初の画面で、テスト ケースを追加するソース ファイル (コンパイル単位) および関数を指定します。
  3. [次へ] ボタンをクリックします。
  4. [データ ソースの使用] チェックボックスをオンにし、ドロップダウン リストから適切なデータ ソースを選択します。



  5. テスト ケースの入力と出力を GUI から設定します。
    • 事前条件または事後条件でデータ ソース値を使用するには、事前条件/事後条件のノードをダブル クリックし、適切なデータ ソース列の名前を選択します。データ ソースの値は、たとえば {myColumnName} のように、中括弧 { } で囲まれた列名としてドロップダウン リストに表示されます。
  6. [終了] ボタンをクリックします。新しいテスト ケースがテスト スイートに追加され、生成されたソース コードがエディターに表示されます。

テスト ケース コードからデータ ソースを設定する

C++test で定義したデータ ソースを使って既存のテスト ケース (自動生成またはユーザー定義) をパラメータライズするには、次の操作を行います。

  1. 登録マクロを使って、使用するデータ ソースを指定します。
    CPPTEST_TEST_DS(<TEST_CASE_NAME>,
    CPPTEST_DS("<MANAGED_DATA_SOURCE_NAME>"));
  2. CPPTEST_DS* マクロを使ってデータ ソース値の使い方を指定します (詳細については 「Macros for Accessing Data Source Values」を参照してください)。

Excel シートの値を使って、既存のテスト ケースをパラメータライズします。MyDataSourceForSum という名前のデータ ソースを作成します。

  1. プロジェクトを開きます。
  2. C++test で定義されたデータ ソースとして Excel シートを追加します。
    1. テスト ケース エクスプローラーで、プロジェクト ノードを右クリックし、ショートカット メニューの [新規追加] > [データ ソース] をクリックします。
    2. [Excel] を選択して [終了] ボタンをクリックします。
    3. データ ソースの名前を入力します。ここではMyDataSourceForSum とします。
    4. Excel ファイル (.xls ファイル) の場所を入力します。
    5. (オプション) [列名を表示] チェックボックスをオンにして列の名前を確認します。
    6. [OK] をクリックします。新しいデータ ソースがテスト ケース エクスプローラーに表示されます。
  3. テスト ケース エクスプローラーで、パラメータライズするテスト ケースをダブル クリックします。
  4. テスト スイート ファイル中でテスト ケースを登録している箇所を探します。 例:

    ...
    CPPTEST_TEST(sumTest1);
    ...
  5.  MyDataSourceForSum データ ソースを使用するよう変更します。

    ...
    CPPTEST_TEST_DS(sumTest1, CPPTEST_DS("MyDataSourceForSum")); 
    ...
  6. テスト ケースの定義に移動し、データ ソース列の値を使用するためのコードを追加します。 「Macros for Accessing Data Source Values」のマクロを使用します。
    例:
 ...
    /* CPPTEST_TEST_CASE_BEGIN sumTest1 */     
    void MyTestSuite::sumTest1()
    {
	int iVal = CPPTEST_DS_GET_INTEGER("i"); 
	int jVal = CPPTEST_DS_GET_INTEGER("j");
	int expectedResult = CPPTEST_DS_GET_INTEGER("result"); 
	CPPTEST_ASSERT_INTEGER_EQUAL(expectedResult, sum(iVal, jVal));
    }
    /* CPPTEST_TEST_CASE_END sumTest1 */

テスト ケースを実行すると、Excel タイプの MyDataSourceForSum データ ソースの値を使ってテスト ケースがパラメータライズされます。

マクロを使ったデータ ソース値へのアクセス

次のマクロを使ってデータ ソース値にアクセスできます。 各マクロはパラメーターとして NAME を取ります。 NAME にはデータ ソース列の一意な識別子を指定します。

実行する操作使用するマクロ備考
NULL 終了文字列の値を返します。

const char*
CPPTEST_DS_GET_CSTR(const char* NAME)

N/A
char 値を返します

char

CPPTEST_DS_GET_CHAR(const char* NAME)

N/A
整数値を返します

long long
CPPTEST_DS_GET_INTEGER(const char* NAME)

N/A
符号なし整数値を返しますunsigned long long CPPTEST_DS_GET_UINTEGER(const char* NAME)N/A
浮動小数点値を返しますlong double CPPTEST_DS_GET_FLOAT(const char* NAME)N/A
論理値を返しますint
CPPTEST_DS_GET_BOOL(const char* NAME)
N/A
メモリ バッファーを返しますconst char*
CPPTEST_DS_GET_MEM_BUFFER (const char* NAME, unsigned int* SIZE_PTR)
SIZE_PTR が null ではない場合、バッファー サイズが SIZE_PTR に格納されます。
列挙値を返します

<scoped enum name>

CPPTEST_DS_GET_ENUM(<scoped enum name>, const char* NAME)

<scoped enum name> は、名前空間名を含む列挙型の完全名です。例: INNER_NS::MyEnumeration, INNER_NS::MyClass::MyEnumeration 
SOURCE 配列からの値を返しますCPPTEST_DS_GET_VALUE(SOURCE)

配列型の変数を SOURCE パラメーターとして指定します。

値が抽出される行の番号は、今後テスト ケースが実行されるたびに自動的に増加します。

現行の反復 (行番号) を返します。unsigned int
CPPTEST_DS_GET_ITERATION( )
現在の反復/行番号を確認するために使用できます。

int
CPPTEST_DS_HAS_COLUMN(const char* name)
スタブの中でテスト ケース固有の振る舞いを実行するために使用できます。(「スタブでのデータ ソースの使用」を参照してください)。データ ソースが使用されていない場合はゼロを返します。

データ ソース値の形式

次の表は、サポートされるデータ ソース値の形式をデータ型ごとにまとめたものです。

データ ソースの型C++test API 関数サポートされる形式
boolCPPTEST_DS_GET_BOOLEAN()

true の場合:

    • true
    • ゼロではない整数定数。たとえば 1

false の場合

    • false
    • 0
signed integerCPPTEST_DS_GET_INTEGER()

整数の 10 進表現 (任意に - 符号または + 符号を前に付ける)。たとえば

    • 0
    • 1
    • -200
    • +55

0x または 0X で開始する、整数の 16 進表現 (任意に - 符号または + 符号を前に付ける)。たとえば

    • 0x1a
    • -0XFF
    • +0x12

0 で開始する 8 進表現(任意に - 符号または + 符号を前に付ける)。たとえば

    • 0711
    • -0123
    • +055

0b または 0B で開始する、整数の 2 進表現(任意に - 符号または + 符号を前に付ける)。たとえば

    • 0b01010101
    • -0B1111
    • +0b11
unsigned integerCPPTEST_DS_GET_UINTEGER()

整数の 10 進表現。たとえば

    • 0
    • 1
    • 200

0x または 0X で開始する、整数の 16 進表現。たとえば

    • 0x1a
    • 0XFF

0 で開始する、整数の 8 進表現。たとえば

    • 0711
    • 0123

0b または 0B で開始する、整数の 2 進表現。たとえば

    • 0b01010101
    • 0B1111
floating pointCPPTEST_DS_GET_FLOAT()

浮動小数点の値の実際の形式は、使用するコンパイラの設定によって異なります。CPPTEST_STR_TO_FLOAT / CPPTEST_SCANF_FLOAT /
CPPTEST_SCANF_FLOAT_FMT マクロの実際の実装です。ほとんどの場合、一連の 10 進数字には基数文字 (小数点、ロケールに依存、通常は ''.'') が含まれます。

また、10 進指数を後に付けることもできます。10 進指数は、 ''E'' または ''e'' の後ろに任意でマイナス符号またはプラス符号が付き、その後ろにスペースを空けずに 10 進数字が続く形式を取ります。10 進指数は 10 の累乗を表します。

例:

    • 100
    • 1.5
    • -3.14159
    • 0.44E7
    • 99.99e-15
charCPPTEST_DS_GET_CHAR()

使用される文字。たとえば

    • a
    • 0
    • $

特別な文字を扱うには、次の C 言語に似たエスケープ シーケンスを使用します。

    • \n
    • \t
    • \v
    • \b
    • \r
    • \f
    • \a
    • \\
    • \'
    • \"

印刷不可の文字の場合、文字の 8 進表現 (\ で開始する 1-3 桁) または 16 進表現 (\x で開始する 1-2 桁) を使用できます。たとえば

    • \13
    • \017
    • \x0A
stringCPPTEST_DS_GET_CSTR()

使用される文字列。たとえば

    • abcdefgh
    • qaz123
    • Hello world!

特別な文字を扱うには、次の C 言語に似たエスケープ シーケンスを使用します。

    • \n
    • \t
    • \v
    • \b
    • \r
    • \f
    • \a
    • \\
    • \'
    • \''

例:

    • Hello, \"world\"!

文字列中の印刷不可文字には、文字の 8 進表現 (\ で開始する 1-3 桁) または 16 進表現 (\x で開始する 1-2 桁) を使用できます。たとえば

    • \13
    • \017
    • \x0A

データ ソース中で C 文字列値として NULL を定義するには、特別な値の接頭辞として $ などの文字を認識するよう、C++test で定義されたデータ ソースを設定し、この接頭辞を NULL の前に付けてデータ ソース中で使用することができます。たとえば

    • $NULL

なお、これは GUI 定義のデータ ソースでだけ使用できます (CPPTEST_DS("ds_name") マクロで登録されたテスト ケース)。

data bufferCPPTEST_DS_GET_MEM_BUFFER()文字列型と同じ形式を使用します (上記を参照)。
enum valueCPPTEST_DS_GET_ENUM()

単純な列挙子名またはすべての名前空間名を含む完全な名前を使用できます。たとえば、列挙子 MON が ::INNER_NS::MyClass::DaysEnumeration に定義されている場合、MON または ::INNER_NS::MyClass::MON と入力できます。

Data Sources および Parameters ステップで列挙子を使用するには、テスト コンフィギュレーションのオプション [列挙データの自動生成を有効化] を有効にします。このオプションは、[テスト コンフィギュレーション] > [実行] タブ > [全般] タブの [インストゥルメント モード] > [編集] > [インストゥルメント機能] > [詳細] にあります。


次の表は、特定のデータ ソース型を使用してソース値の形式を指定するための情報です。

データ ソースの型データ ソース登録マクロ備考
CSV ファイル (C++test で定義されたデータ ソース)CPPTEST_DS()

データ ソースの値は、引用符で囲まれていることがあります (引用符の符号はデータ ソースの設定で定義することができます)。たとえば

    • "Hello world!"

変数中で区切り文字を使用する必要がある場合、または変数中で引用符号そのものを使用する必要がある場合、引用符で囲むことが必要です。変数中で引用符号そのものを使用する場合には、データ ソース値の要素として使用される引用符号を二重にする必要があります。たとえば

    • "Hello world!"
    • "Hello, \""world\""!"
Excel シート (C++test で定義されたデータ ソース)CPPTEST_DS()

Excel 特有の値の準備は必要ありません。上記の「データ ソース値の形式」の説明にあるように、データの型に合った形式を使用する必要がある点に注意してください。

確実に C++test で値を適切に処理するために、スプレッド シート中のすべてのセルで表示形式として「文字列」を使用できます。この方法によって、たとえば整数の 8 進表現を確実に正しく処理することができます。

表 (C++test で定義されたデータ ソース)CPPTEST_DS()表に特有の値の準備は必要ありません。上記の「データ ソース値の形式」の説明にあるように、データの型に合った形式を使用する必要がある点に注意してください。
CSV ファイルCPPTEST_DS_CSV()

データ ソースの値は、引用符で囲まれていることがあります (引用符の符号はデータ ソースの設定で定義することができます)。たとえば

    • "Hello world!"

変数中で区切り文字を使用する必要がある場合、または変数中で引用符号そのものを使用する必要がある場合、引用符で囲むことが必要です。変数中で引用符号そのものを使用する場合には、データ ソース値の要素として使用される引用符号を二重にする必要があります。たとえば

    • "Hello, world!"
    • "Hello, \""world\""!"
ソース コード配列CPPTEST_DS_ARRA Y()配列特有の値の準備は必要ありません。上記の「データ ソース値の形式」の説明にあるように、データの型に合った形式を使用する必要がある点に注意してください。

データベース (C++test で定義されたデータ ソース)CPPTEST_DS()データベース特有の値の準備は必要ありません。上記の「データ ソース値の形式」の説明にあるように、データの型に合った形式を使用する必要がある点に注意してください。

利用可能なデータ ソースの参照

データ ソースの構成を参照/変更する

既存のデータ ソースの構成を参照または変更するには、次の操作を行います。

  • テスト ケース エクスプローラーで、データ ソースのノードを右クリックし、ショートカット メニューの [編集] をクリックします。


表示された画面で、データ ソースの構成を参照したり、必要に応じて変更できます。

データ ソース ファイルを開く

データ ソース ファイルを開くには、次の操作を行います。

  • [テスト ケース エクスプローラー] ビューでデータ ソースのノードを右クリックし、ショートカット メニューの [データ ファイルを開く] をクリックします。

データソースの共有

プロジェクト レベルまたはテスト スイート レベルで追加されたデータ ソースについての情報は、各プロジェクト中にある .parasoft プロパティ ファイルに格納されます。この .parasoft プロパティ ファイルをソース管理システムにコミットすれば、データ ソースについての情報を共有することができます。


ワークスペースレベルで追加されたグローバル データ ソースも同様に共有できます。ただし、グローバル データ ソースの情報を格納した .datasources.properties ファイルの作成場所 (たとえばプロジェクトなど) をユーザーが定義する必要があります。デフォルトでは、グローバル データ ソースの情報はローカルに格納されます。

共有するグローバル データ ソースの場所を指定します。

  1. [Parasoft] メニューの [設定] をクリックします。[設定] ウィンドウを表示します。
  2. 左側のリストから [Parasoft] > [グローバル データ ソース] を選択します。
  3. datasources.properties ファイルの保存先を指定します。

データ ソースの移植性の保証 (ポータブル モード)

データ ソース ポータブル モードは、テスト スイート ファイルを別の場所に移動する必要がある特定の開発環境を扱うために設計されたモードです。標準データ ソース モードでは、別の場所にテスト スイート ファイルを移動する場合、データ ソースの関連付けが失われます。ポータブル モードでは、テスト スイートと共にデータ ソースを簡単に移動できます。

データ ソースの移植性を保証するために、テスト スイート ファイルと同じ名前で拡張子が .properties のファイルに、テスト スイート レベルのすべてのデータ ソース情報が格納されます。結果として、テスト スイートごとにデータ ソース設定ファイルが作成され、このデータ ソース設定ファイルはデータと共に移動できます。


ポータブル データ ソース モードは、テスト スイート レベルで作成されたデータ ソースにだけ適用されます。プロジェクトまたはワークスペースレベルで作成されたデータ ソースには適用されません。

データ ソース モードを変更する

データ ソースの設定を変更するには、次の操作を行います。

  1. プロジェクト ノードを右クリックし、 [プロパティー] をクリックします。

  2. 左側のリストから [Parasoft] > [C++test] > [データ ソース] を選択します。
  3. [ポータブル データ ストレージを使用] の設定を変更し、[適用] または [OK] ボタンをクリックします。




モードを切り替えるたびに、テスト スイートに関連する既存のすべてのデータ ソースが、選択されたモードに自動的に変換されます。ポータブル モードに切り替えると、データ ソースの設定が .parasoft ファイルから、対応する <test_suite_name>.properties ファイルに転送されます。変換が完了すると、メッセージが通知されます。



すべての *.properties ファイルまたは選択した *.properties ファイルをコミットおよびチェックアウトすることで、ソース管理システムを介してデータ ソース情報を共有できます。

Excel または CSV データ ソース ファイルへの相対パスを使用する

Excel および CSV データ ソース タイプについてより良い移植性を保証するために、C++test の ${test_suite_loc} 変数を Excel/CSV ファイルのパスで使用できます。この変数は、テスト スイート ファイルがある場所への絶対パスに解決されます。


C++test の外部で定義された配列と CSV ファイルをデータ ソースとして使用するための設定

管理されたデータ ソース (上記のとおり C++test で定義されたデータ ソース) のほかに、C++test の外部で定義された配列と CSV ファイルの値をデータソースで使用することができます。

配列データ ソース値を使用する

C++test でのデータ ソース実装の 1 つは型付き配列をベースにしています。これは、テストでデータ行を順番に読み取るために使用されます。

データ ソースにアクセスできるテスト ケースを作成するには、次の操作を行います。

  • CPPTEST_TEST_DS(testCaseName, dataSourceConfig) マクロを使ってテスト ケースを登録します。

マクロ中の testCaseName は、データ ソース値にアクセスするテスト ケース関数名で置き換えます。dataSourceConfig は、データ ソース設定用のヘルパー マクロで置き換えます。

dataSourceConfig として次の 2 つのヘルパー マクロを使用できます。CPPTEST_DS_ARRAY(ARRAY_NAME, ROW, COLUMN) および CPPTEST_DS_REPEAT(NUMBER)

CPPTEST_DS_ARRAY(ARRAY_NAME, ROW, COLUMN) を使用するときは、次の点に注意してください。

  • このマクロは ARRAY_NAME をデータ ソースとして使用します。ARRAY_NAME は const char* data[ROW][COLUMN] 型でなければなりません。
  • テーブルの 1 行目は列名でなければなりません。
  • テスト ケースは (ROW - 1) 回実行されます。
  • データ ソース アクセス マクロを使って、値を抽出できます。詳細については次のセクションを参照してください。


CPPTEST_DS_REPEAT(NUMBER) を使用するときは、次の点に注意してください。

  • テスト ケースは NUMBER 回だけ実行されます。
  • テスト ケースはカスタム データ配列からの値にアクセスするために使用できます。詳細については 「Macros for Accessing Data Source Values」のCPPTEST_DS_GET_VALUE および CPPTEST_DS_GET_ITERATION の説明を参照してください。

ヒント

  • C++ テスト スイートの場合、データ ソース配列は、テスト スイート クラスの外部で宣言することも、テスト スイート クラスのメンバーとして宣言することもできます。C テスト スイートの場合はテスト スイート クラスの外部でしか宣言できません。 なお、C++ テスト スイートをビルドする C++ コンパイラがあれば、C++ テスト スイートを C 言語のために使用できます。
  • データ ソース配列をクラス メンバーとして宣言する場合、アクセスのスコープは重要ではありません。なぜなら、配列にアクセスするのはテスト ケース関数と setup/teardown 関数だけであり、これらの関数はメンバー関数だからです。
  • 型を指定した配列を宣言して setUp メソッドで初期化することは、データ ソース配列を任意データに初期化する強力な方法です。動的にアロケートされたオブジェクト、ファクトリ テスト オブジェクトなどに初期化できます。サンプル コードを以下に記載します。


#include "cpptest.h" 
int plus_one(int);
class TestSuite_3 : public CppTest_TestSuite {
public:
    CPPTEST_TEST_SUITE(TestSuite_3);
    CPPTEST_TEST_DS(test_ds_repeat, CPPTEST_DS_REPEAT(2));     
    CPPTEST_TEST_SUITE_END();
 
    void setUp();
    void tearDown();
 
    void test_ds_repeat();
private:
    int _dsRepeat_arg[2];
    int _dsRepeat_return[2];
};
CPPTEST_TEST_SUITE_REGISTRATION(TestSuite_3); 
 
void TestSuite_3::setUp()
{
    _dsRepeat_arg[0] = 1;
    _dsRepeat_arg[1] = 2;
}
void TestSuite_3::tearDown()
{
}
void TestSuite_3::test_ds_repeat()
{
    int index = CPPTEST_DS_GET_ITERATION() - 1;
    int _value = _dsRepeat_arg[index];
    int _expected = _dsRepeat_return[index];
 
    int _return = plus_one(_value);
    CPPTEST_ASSERT_INTEGER_EQUAL(_expected, _return);
}

C++test の外部で定義された CSV データ ソースを使用する

CSV データが次の条件を満たす場合、C++test の外部で定義された CSV データ ソースを使用できます。

  • CSV データが外部ファイルに格納されている。
  • CSV データのレコード (行) は、区切り文字で区切られた値である (区切り文字はカスタマイズ可能)。
  • CSV データはヘッダーを持つことができる。
  • CSV データ値としてスペース文字を使用できる。スペース文字は無視することもできる。

サポートされるファイル タイプについては 「CSV File Support Details」 を参照してください。

CSV データ ソースにアクセスできるテスト ケースを作成するには、次の操作を行います。

  • CPPTEST_TEST_DS(testCaseName, dataSourceConfig) マクロを使ってテスト ケースを登録します。

マクロ中の testCaseName は、データ ソース値にアクセスするテスト ケース関数名で置き換えます。dataSourceConfig は、CPPTEST_DS_CSV(FILE_NAME, SEPARATOR, HAS_HEADER, TRIM) で置き換えます。

CPPTEST_DS_CSV は C++test Data Source API で定義されています。パラメーターは次のとおりです。

  • FILE_NAME - データ ソースがあるデータ ソース ファイルの名前。  絶対パスでも相対パスでも指定できます。
    注意: 相対パスで指定する場合、このパスはテスト用実行モジュールの作業ディレクトリからの相対になります。作業ディレクトリはテスト コンフィギュレーションの [実行] > [実行時] タブの [テスト用実行モジュールの実行ディレクトリ] フィールドで指定できます。
  • SEPARATOR - フィールド区切り子。カンマなどの文字定数を指定する必要があります。(例: ',')。
  • HAS_HEADER - データの 1 行目がヘッダーの場合、1 に設定します。ヘッダーがない場合、0 に設定します。
    注意: CSV ファイルにヘッダーがない場合、列名は 0 から開始する序数になります。
  • TRIM - 値の前または後のスペースを削除する場合、1 に設定します。ヘッダーがない場合、0 に設定します。

CSV ファイルにヘッダーがない場合、フィールド名は 0 から開始する序数になります。値は引用符で囲んで指定します。例: CPPTEST_DS_GET_FLOAT("0");

FILE_NAME は完全ファイル パスでも相対ファイル パスでもかまいません。相対パスの場合、現在のディレクトリに対する相対パスです。

CPPTEST_DS_CSV の例

CPPTEST_DS_CSV("/home/project/testdata.csv", ',', 1, 0)

  • /home/project/testdata.csv をデータ ファイルとして使用します。
  • 値はカンマ (,) で区切ります。
  • 1 行目のデータはヘッダーとして処理します。
  • 値の前後のスペースは削除しません。

CPPTEST_DS_CSV("testdata.csv", ';', 0, 1)

  • 現行ディレクトリの testdata.csv をデータ ファイルとして使用します。
  • 値はセミコロン (;) で区切ります。
  • ヘッダーはありません。1 行目をデータとして処理します。
  • 値の前後のスペースを削除します。

CSV ファイルのサポートについて

  • 改行して (CRLF) を使って 1 つのレコードを 1 つの行にします。  例:
    aaa,bbb,ccc CRLF
    zzz,yyy,xxx CRLF
  • ファイルの最後のレコードには、改行はあってもなくても構いません。  例:
    aaa,bbb,ccc CRLF
    zzz,yyy,xxx
  • ファイルの 1 行目にヘッダーを置くことができます。ヘッダーはレコードと同じ書式および数でなければなりません。  ヘッダーの有無は この MIME タイプの header パラメーターで指定できます。 
    例:
    aaa,bbb,ccc CRLF
    zzz,yyy,xxx CRLF
  • ヘッダーおよび各レコードには、カンマで区切った 1 つ以上のフィールドを置くことができます。フィールドの数は、ファイル中のすべてのレコード行で同じでなければなりません。   スペースはフィールドの一部と見なされます。  レコードの最後のフィールドの後にカンマを置いてはいけません。  例:
    aaa,bbb,ccc
  • 各フィールドは、二重引用符で囲んでも囲まなくても構いません。ただし、Microsoft Excel などの一部のプログラムは二重引用符を使用しません。  二重引用符でフィールドを囲まない場合、フィールド中で二重引用符を使用してはいけません。  例:
    "aaa","bbb","ccc" CRLF
    zzz,yyy,xxx
  • 改行 (CRLF)、二重引用符、カンマがあるフィールドは、二重引用符で囲みます。  例:
    "aaa","b CRLF
    bb","ccc" CRLF
    zzz,yyy,xxx
  • 二重引用符を使ってフィールドを囲む場合、フィールド中の二重引用符は、二重引用符を 2 つ重ねてエスケープしなければなりません。  例:
    "aaa","b""bb","ccc"
  • CRLF ではなく LF をレコードの改行に使用できます。
  • 値の前および後のスペースは削除できます。
  • レコード中に同じ数の値は必要ありません。
  • カンマ以外の文字もフィールド区切り子として使用できます。

データ ソースの使用例
CPPTEST_DS_ARRAY の使用例

この例では、配列データ ソースを使用します。まず、データの配列を定義します。

const char* MyData[][3] = {
    { "arg1",  "arg2", "return" },
    {    "1",	"one",	  "111" },
    {	 "0",   "two",    "222" },
    {    "2", "three",    "333" },
};

この配列は 3 列 4 行です。 1 行目の arg1arg2return は列の名前です。残りの 3 行はテスト ケースのデータです。つまり、3 個のテスト ケースが実行されます。 データを用意したら、次のようにテスト ケースを登録します。

	CPPTEST_TEST_DS(testFoo2, CPPTEST_DS_ARRAY(MyData, 4, 3));

テスト ケース testFoo2 は、 MyData 配列のデータを使って 3 回実行されます。最後に、テスト ケースを記述します。テストされる関数は 2 つのパラメーターを持ち、整数を返します。 データ ソースから 2 つのパラメーターに値を渡すために、次のようにコードを記述します。

  int arg1 = CPPTEST_DS_GET_INTEGER("arg1");     
    const char * arg2 = CPPTEST_DS_GET_CSTR("arg2");

指定の名前の列がない場合、または値の型が一致しない場合、テスト ケースは実行されません。

事後条件のチェックのために、次のように期待値をデータ ソースから取得します。

 int expectedReturn = CPPTEST_DS_GET_INTEGER("return");
    /* check return value with value from data source */     
    CPPTEST_ASSERT_INTEGER_EQUAL(expectedReturn, actualReturn);

完成したテストは次のとおりです。

class TestWithDataSource : public CppTest_TestSuite 
{
public:
    CPPTEST_TEST_SUITE(TestWithDataSource);
 
    /* register standard test case */     
    CPPTEST_TEST(testFoo1);
 
    /* register test case with "MyData" data source access */     
    CPPTEST_TEST_DS(testFoo2, CPPTEST_DS_ARRAY(MyData, 4, 3));
 
    CPPTEST_TEST_SUITE_END();
...
...
...
 
/* test case using values from data source */
void TestWithDataSource::testFoo2()
{
    /* extract arguments from data source */
    int arg1 = CPPTEST_DS_GET_INTEGER("arg1");
    const char * arg2 = CPPTEST_DS_GET_CSTR("arg2");
 
    /* call tested function */
    int actualReturn = foo(arg1, arg2);
 
    /* extract expected return from data source */
    int expectedReturn = CPPTEST_DS_GET_INTEGER("return");
 
    /* check return value with value from data source */
    CPPTEST_ASSERT_INTEGER_EQUAL(expectedReturn, actualReturn);
}

CPPTEST_DS_REPEAT の使用例

この例では repeat データ ソースを使用します。

/* data source for arg1 */
int _arg1[] = {
     1,
     0,
     2,
};
 
/* data source for arg2 */
const char * _arg2[] = {
   "one",    
   "two",
   "three",
};
/* data source for return */
int _return[] = {
   111,
   222,
   333,
};

これは特別なデータ ソースです。データへのアクセスはなく、指定の回数テスト ケースを実行するだけです。ユーザーはテストを実行するたびにどのデータを使用するかを指定します。この例では、3 つの配列を使用します。_arg1_arg2、および _return です。

テスト ケースを登録します。

CPPTEST_TEST_DS(testFoo2, CPPTEST_DS_REPEAT(3));

CPPTEST_DS_REPEAT パラメーターはテスト ケース testFoo2 を実行する回数を表します。

このテスト ケースでは配列から直接データを取得します。適切な行から値を取得するために、 CPPTEST_DS_GET_ITERATION() の値を配列インデックスとして使用することも、 CPPTEST_DS_GET_VALUE(SOURCE) マクロにインデクシングを実行させることもできます。

 int arg1 = CPPTEST_DS_GET_VALUE(_arg1);
    const char * arg2 = CPPTEST_DS_GET_VALUE(_arg2);

CPPTEST_DS_GET_VALUE マクロには型の範囲チェックはありません。配列インデックスだけです。

完成したテストは次のとおりです。

class TestWithDataSource : public CppTest_TestSuite 
{
public:
    CPPTEST_TEST_SUITE(TestWithDataSource);
 
    /* register standard test case */
    CPPTEST_TEST(testFoo1);
 
    /* register test case that will be executed number of times */
    CPPTEST_TEST_DS(testFoo2, CPPTEST_DS_REPEAT(3));
 
    CPPTEST_TEST_SUITE_END();
...
...
...
 
/* test case using values from custom arrays */
void TestWithDataSource::testFoo2()
{
    /* extract arguments from data source */
    int arg1 = CPPTEST_DS_GET_VALUE(_arg1);
    const char * arg2 = CPPTEST_DS_GET_VALUE(_arg2);
 
    /* call tested function */
    int actualReturn = foo(arg1, arg2);
 
    /* extract expected return from data source */
    int expectedReturn = CPPTEST_DS_GET_VALUE(_return);
 
    /* check return value with value from data source */
    CPPTEST_ASSERT_INTEGER_EQUAL(expectedReturn, actualReturn);
}

CPPTEST_DS_CSV の使用例

CVS データ ソース ファイル /home/test/t2.data に格納されたデータを使用します。ヘッダーとフィールドはカンマで区切られています。トリミングは使用していません。

class TestSuite : public CppTest_TestSuite 
{
	public:
	CPPTEST_TEST_SUITE(TestSuite);
	CPPTEST_TEST_DS(test_fooc_1, CPPTEST_DS_CSV("/home/test/t2.data",',', 1, 0));
	CPPTEST_TEST_SUITE_END();
 
	void setUp(); 
	void tearDown();
 
	void test_fooc_1();
};

Data Source API の標準関数を使用するテスト ケースの定義です。

void TestSuite::test_fooc_1()
{
	int _boo  = CPPTEST_DS_GET_INTEGER("first");
        float _goo  = CPPTEST_DS_GET_FLOAT("second");
 
	int _return  = fooc(_boo, _goo, _g);
	CPPTEST_ASSERT_INTEGER_EQUAL(CPPTEST_DS_GET_INTEGER("result"), ( _return ))
}

CSV データ ソース ファイル /home/test/t2.data の中身は次のようになっています。ヘッダーと 3 つのフィールドがあります。

first,second,result
1,2,3
2,2,4
2,2,5

回帰テストをベースにしたデータ ソースの作成

サンプル プロジェクトの ATM プロジェクトをテストするデータ ソース ベースの回帰テストを 2 つ作成します。1 つは文字列の配列データを使用し、もう 1 つは型付き配列データを使用します。ATM プロジェクトは C++test の Examples ディレクトリにあります。

  1. プロジェクトのノードを右クリックし、 [新規] メニューの [その他] > [C++test] > [テスト スイート]をクリックして[次へ] ボタンをクリックします。テスト スイート ウィザードが表示されます。

  2. [テスト スイートの名前] に TestSuiteAccount を指定し、[テスト スイートの場所] に ATM/tests/user を指定します(ディレクトリが存在しない場合は [Create Directory] をクリックします)。TestSuiteAccount は C++ テスト スイートのクラス名になります。
  3. [テスト スイートの言語] として [C++] をクリックします。
  4. その他のすべてのオプションはそのままにします。
  5. [次へ] ボタンをクリックします。[追加] ボタンを 2 回クリックして Account クラスの 2 つのテストを追加します。 テスト名は setPasswordTestdepositTest にします。ウィザードを終了すると、これらのテストがあるスケルトン テスト スイートが適切に登録されます。
  6. テスト スイート ソース ファイルを開きます。
  7. パスワード設定のテスト用に文字列のデータ ソース配列を作成します (下記を参照)。 この配列をテスト スイートのソース ファイルでテスト スイート クラス宣言の上に記述します。一般的に、言語の慣用的な語法に従って、データ ソース配列はファイル スコープで宣言するかテスト スイート クラスの静的メンバーとして宣言します。

    const char* passwordData [] [2] = {
    	{ "arg1", "result" },
    	{ "", "" },
    	{ "a1", "a1" },
    	{ "really_long_password", "really_long_password" },
    	{ "foo", "goo" }
    };
  8. setPassword メソッドのテスト ケースを作成します。このテストはパスワードをセットし、返されたパスワードがデータ ソースで指定されているパスワードと一致するかをチェックします。

    void TestSuiteAccount::setPasswordTest()
    {
    	const char* password = CPPTEST_DS_GET_CSTR("arg1");
    	const char* result = CPPTEST_DS_GET_CSTR("result");
    	Account _cpptest_object;
    	_cpptest_object.setPassword(password);
    	CPPTEST_ASSERT_CSTR_EQUAL(result, _cpptest_object.getPassword())
    }
  9. ファイルの先頭に #include "Account.hxx" を追加して Account クラスの宣言を取得します。
  10. テスト スイート宣言のテスト ケース登録 CPPTEST_TEST(setPasswordTest) を次のように変更します。

     CPPTEST_TEST_DS(setPasswordTest, CPPTEST_DS_ARRAY(passwordData, 5, 2));
  11. ユーザー定義テストを実行するユーザー定義テスト コンフィギュレーションを作成します。
    1. [Parasoft] メニューの [テスト コンフィギュレーション] をクリックします。
    2. [ビルトイン] > [Unit Testing] テスト コンフィギュレーションを右クリックして [複製] をクリックします。
    3. 複製したユーザー定義コンフィギュレーションの名前を 「Run DS Tests」に変更します。
    4. [実行] タブの [全般] タブをクリックします。
    5. テスト スイートの場所のパターンを変更して /tests/user/* のテストだけに限定します。
    6. [適用] ボタンをクリックしてから [OK] ボタンをクリックして変更を保存します。
  12. プロジェクトのノードを選択し、新しく作成した [Run DS Tests] テスト コンフィギュレーションを実行します。
  13. テストが完了したら [品質タスク] ビューを参照します。「単体テストの問題の修正」カテゴリに 2 つの単体テスト アサーションがあります。1 つはデータ ソースの 4 行目をポイントしています。4 行目のデータは、回帰テストの失敗をシミュレーションするために用意された意図的に不正なデータです。 もう 1 つは 2 つ目のテスト ケースからのアサーションです。
  14. 型付き配列のデータを使って 2 つ目のテスト ケースを作成します。預金の値を格納する double 型のデータ ソース配列と 、口座残高の値を格納する double 型のデータ ソース配列を作成します。そしてテスト スイートの配列メンバーを作成します。テスト スイート宣言の最後は次のようになります。

     		void depositTest();
    	private:
    		static double deposit []; 
    		static double balance [];
    };
    		double TestSuiteAccount::deposit [] = {
    			0.0,
    			1.0,
    			-2.0,
    			1e06
    		};
    		double TestSuiteAccount::balance [] = {
    			1.0,
    			2.0,
    			-1.0,
    			1000001.0
    };
  15. deposit 関数のテストを作成し、回帰テストとして最終残高をチェックします。

    void TestSuiteAccount::depositTest()
    {
    	double dep_value = CPPTEST_DS_GET_VALUE(deposit);
    	double balance_value = CPPTEST_DS_GET_VALUE(balance); 
    	Account _cpptest_object(1.0);  // create account with initial deposit
    	_cpptest_object.deposit(dep_value); // additional deposit
    	CPPTEST_ASSERT_DOUBLES_EQUAL(balance_value, _cpptest_object.getBal-ance(), 1e-6)
    }
  16. CPPTEST_TEST(depositTest) テストの登録を 4 回に変更します。

     CPPTEST_TEST_DS(depositTest, CPPTEST_DS_REPEAT(4));
  17. Run DS Tests テスト コンフィギュレーションを使ってプロジェクトをテストします。
  18. [品質タスク] ビューの「単体テストの問題の修正」カテゴリを参照します。新しいテストではすべての値が一致するため、タスクはレポートされません。