次の方法で共有


PICT データ ソース

このセクションに進む前に、TAEF の基本的な実行と、それを使用してテストを作成する方法を理解していることを確認してください。

PICT の背景と参照

PICT は、Pairwise Independent Combinatorial Testing (ペアワイズ法による独立した組み合わせテスト) の略です。 PICT を使用すると、パラメーターごとにバリエーションを個別に指定できます。 たとえば、API テストが FileName と FileExtension の 2 つのパラメーターに依存している場合、FileName と FileExtension に個別に渡す可能性のあるバリエーションは、次のものが考えられます。

  • FileName: a、z12390、Realllyreallyreallylonglonglonglonglonglonglonglonglonglong、normallength
  • FileExtension: txt、png、bat、doc、exe、bmp、wav

リストに追加するバリエーションが増えると、上記の総当たりの組み合わせ (4 X 7 = 28) が簡単に限界を超えることがわかるでしょう。 このようなテスト ケースのシナリオでは、PICT は、パラメーター結果のコンパクトなセットを生成して入力パラメーターに対する包括的な組み合わせ範囲を取得することで、多くの値を追加できます。

TAEF での PICT サポート

TAEF では、PICT ベースのテストに対する組み込みのサポートが提供されます。

これを利用するには、通常と同様に、pict.exe 用の入力モデル ファイルを記述します。 上記の examples フォルダーの *.txt ファイルを参照してください。 PICT がモデル ファイルで想定どおりに実行される場合は、まず次のようにコマンド プロンプトで試してみると便利な場合があります。

pict.exe <model file> [/e:<seed file>]

pict.exe は、TAEF の最新リリース共有の残りのバイナリで使用できます。

PICT のモデル ファイル (およびシード ファイル) の作成が完了し、コマンド プロンプトで pict.exe に対して検証を行ったら、TAEF に PICT 駆動テストであることを知らせるためテストをマークすることができます。 TAEF で使用できるテーブル ベースのデータドリブン テストに慣れている場合は、この方法が非常によく似ていることがわかるでしょう。

ネイティブ コード:

1     class PictExample
2     {
3         TEST_CLASS(PictExample)
4
5         BEGIN_TEST_METHOD(SimpleTest)
6             TEST_METHOD_PROPERTY(L"DataSource", L"pict:PictExample.txt")
7         END_TEST_METHOD()
8
9         BEGIN_TEST_METHOD(TestWithSeed)
10            TEST_METHOD_PROPERTY(L"DataSource", L"pict:TestWithSeed.txt")
11            TEST_METHOD_PROPERTY(L"Pict:SeedingFile", L"TestWithSeed.sed")
12            TEST_METHOD_PROPERTY(L"Pict:Timeout", L"00:01:30")
13        END_TEST_METHOD()
14
15        BEGIN_TEST_METHOD(TestWithFunction)
16            TEST_METHOD_PROPERTY(L"DataSource", L"pict:TestWithFunction.txt")
17        END_TEST_METHOD()
18    };

マネージド コード:

1     [TestClass]
2     public class CSharpPictExample
3     {
4         [TestMethod]
5         [DataSource("pict:ConstraintsTest.txt")]
6         [TestProperty("Pict:SeedingFile", "ConstraintsTest.seed")]
7         public void ConstraintsTest()
8         {
9             ...
10        }
11
12        [TestMethod]
13        [DataSource("pict:SumofSquareRoots.txt")]
14        public void SumOfSquareRoots()
15        {
16            ...
17        }
18
19        public TestContext TestContext
20        {
21            get { return m_testContext; }
22            set { m_testContext = value; }
23        }
24
25        private TestContext m_testContext;
26    }

上の例に示すように、モデル ファイルの名前を DataSource として指定する必要があります。 モデル ファイルの名前の前に "pict:" を付け、テスト メソッドの DataSource として指定します。 TAEF を使用する他のデータ ドリブン テストと同様に、マネージド テストの場合は、TestContext プロパティの get メソッドと set メソッドを提供し、クラス内に同じプロパティのプライベート インスタンスを作成する必要があります。

コマンド オプションを PICT に渡す場合は、この目的でメタデータを使用できます。 次の表を使用して、Pict.exe のコマンド オプションを TAEF メタデータにマップします。

pict.exe コマンド構文 ネイティブ TAEF メタデータ構文 マネージド TAEF メタデータ構文
/o:3 TEST_METHOD_PROPERTY(L"Pict:Order", L"3") [TestProperty("Pict:Order", "3")]
/d:, TEST_METHOD_PROPERTY(L"Pict:ValueSeparator", L",") [TestProperty("Pict:ValueSeparator", ",")]
/a: TEST_METHOD_PROPERTY(L"Pict:AliasSeparator", L"
/n:~ TEST_METHOD_PROPERTY(L"Pict:NegativeValuePrefix", L"~") [TestProperty("Pict:NegativeValuePrefix", "~")]
/e:test.seed TEST_METHOD_PROPERTY(L"Pict:SeedingFile", L"test.seed") [TestProperty("Pict:SeedingFile", "test.seed")]
/r TEST_METHOD_PROPERTY(L"Pict:Random", L"true") [TestProperty("Pict:Random", "true")]
/r:33 TEST_METHOD_PROPERTY(L"Pict:RandomSeed", L"33") [TestProperty("Pict:RandomSeed", "33")]
/c TEST_METHOD_PROPERTY(L"Pict:CaseSensitive", L"true") [TestProperty("Pict:CaseSensitive", "true")]

上記のメタデータは、コマンド プロンプト、DataSource プロパティ、またはテスト、クラス、またはモジュール レベルのメタデータとして、この順の優先順位で設定できます。 コマンド プロンプトで設定するには、次の構文を使用します。

te.exe <test dll> /Pict:Order=3 /Pict:SeedingFile=test.seed

DataSource プロパティでメタデータを設定するには、モデル ファイル名に疑問符文字 (?) を追加し、メタデータ名 = メタデータ値のペアをアンパサンドで区切って追加します。 このメソッドを使用する場合、メタデータ名の "Pict:" プレフィックスは省略可能です。 例を次に示します。

TEST_METHOD_PROPERTY(L"DataSource", L"Pict:model.txt?Order=3&CaseSensitive=true&Random=true")

TAEF はバックグラウンドで、入力モデル ファイルとコマンド オプションを PICT に提供し、結果を取得します。 PICT でエラーまたは警告が生成された場合は、TAEF によって警告としてログに記録されます。 PICT が生成する結果の出力行ごとに、TAEF は問題のあるテストを再度呼び出します。

"Pict:RandomSeed" の値を設定すると、"Pict:Random" の既定値が false から true に変更されます。 これにより、明示的に "Pict:Random" を false に設定して、TAEF に "Pict:RandomSeed" を無視させることができます。

モデル ファイルとシード ファイルの入力で PICT.exe の実行に許可されている既定のタイムアウトは 5 分です。 モデル ファイルが複雑で、PICT.exe が結果を返すために 5 分を超える時間が必要な場合は、上記の CPP の例に示すように、"Pict:Timeout" メタデータを指定することで、このタイムアウトをオーバーライドできます。 この例では、標準の TAEF タイムアウトの形式で 1.5 分のタイムアウトが指定されています。 他の PICT メタデータと同様に、"Pict:Timeout" メタデータは継承されるため、クラスまたはモジュール全体に対して指定できます。

TAEF を使用したテーブル ベースのデータ ドリブン テストの場合と同じ方法で、次のようにネイティブ コードには TestData クラスを使用し、マネージド コードには TestContext を使用して、テスト メソッドとその関連するセットアップ メソッドおよびクリーンアップ メソッドから特定の呼び出し中にデータ値にアクセスできます。

ネイティブ コード:

1     void PictExample::SimpleTest()
2     {
3         String valueA;
4         if (SUCCEEDED(TestData::TryGetValue(L"A", valueA)))
5         {
6           Log::Comment(L"A retrieved was " + valueA);
7         }
8
9         String valueB;
10        if (SUCCEEDED(TestData::TryGetValue(L"B", valueB)))
11        {
12            Log::Comment(L"B retrieved was " + valueB);
13        }
14
15        String valueC;
16        if (SUCCEEDED(TestData::TryGetValue(L"C", valueC)))
17        {
18            Log::Comment(L"C retrieved was " + valueC);
19        }
20
21        unsigned int index;
22        if (SUCCEEDED(TestData::TryGetValue(L"index", index)))
23        {
24            Log::Comment(String().Format(L"At index %d", index));
25        }
26    }

マネージド コード:

1      [TestClass]
2      public class CSharpPictExample
3      {
4          [TestMethod]
5          [DataSource("pict:ConstraintsTest.txt")]
6          public void ConstraintsTest()
7          {
8              Log.Comment("A is " + m_testContext.DataRow["A"]);
9              Log.Comment("B is " + m_testContext.DataRow["B"]);
10             Log.Comment("C is " + m_testContext.DataRow["C"]);
11             Log.Comment("D is " + m_testContext.DataRow["D"]);
12
13             UInt32 index = (UInt32)m_testContext.DataRow["Index"];
14             Log.Comment("At index " + index.ToString());
15        }
16
17        [TestMethod]
18        [DataSource("pict:SumofSquareRoots.txt")]
19        public void SumOfSquareRoots()
20        {
21             Log.Comment("A is " + m_testContext.DataRow["A"]);
22             Log.Comment("B is " + m_testContext.DataRow["B"]);
23
24             UInt32 index = (UInt32)m_testContext.DataRow["Index"];
25             Log.Comment("At index " + index.ToString());
26        }
27
28        public TestContext TestContext
29        {
30             get { return m_testContext; }
31             set { m_testContext = value; }
32        }
33
34        private TestContext m_testContext;
35    }

TAEF のデータドリブン テストと同様に、"Index" は予約されており、パラメーター名として使用することはできません。 インデックスはテスト メソッド呼び出しのインデックスを暗黙的に参照し、テストで必要な場合はテスト メソッドからアクセスできます。

PICT ベースのテストの場合、すべてのパラメーターのデータ型は WEX::Common::String (ネイティブ)、String (マネージド) または VT_BSTR (スクリプト) であると見なされることにも注意してください。 変換と解釈はユーザーに委ねられます。

これで、TAEF を使用した PICT ベースのテストの作成が完了しました。コマンド プロンプトから呼び出し、TAEF が提供するすべてのコマンド機能を適用できます。たとえば、/list を使用して、PICT 出力をデータとして使用して生成されるすべてのテスト メソッドの一覧を取得したり、/listproperties を使用して、テスト メソッド名の一覧と、それらが関連付けられているメタデータとデータ値を取得したりできます。開始する前に注意すべき重要な点は、pict.exe がパスにあることを確認することです。

次に例をいくつか示します。

te Examples\CPP.Pict.Example.dll /list /name:*SimpleTest*
Test Authoring and Execution Framework v2.9.3k for x86
        f:\ Examples\CPP.Pict.Example.dll
            WEX::TestExecution::Examples::PictExample
                WEX::TestExecution::Examples::PictExample::SimpleTest#0
                WEX::TestExecution::Examples::PictExample::SimpleTest#1
                WEX::TestExecution::Examples::PictExample::SimpleTest#2
                WEX::TestExecution::Examples::PictExample::SimpleTest#3
                WEX::TestExecution::Examples::PictExample::SimpleTest#4
                WEX::TestExecution::Examples::PictExample::SimpleTest#5
                WEX::TestExecution::Examples::PictExample::SimpleTest#6
                WEX::TestExecution::Examples::PictExample::SimpleTest#7
                WEX::TestExecution::Examples::PictExample::SimpleTest#8
                WEX::TestExecution::Examples::PictExample::SimpleTest#9
                WEX::TestExecution::Examples::PictExample::SimpleTest#10
                WEX::TestExecution::Examples::PictExample::SimpleTest#11
                WEX::TestExecution::Examples::PictExample::SimpleTest#12
                WEX::TestExecution::Examples::PictExample::SimpleTest#13
                WEX::TestExecution::Examples::PictExample::SimpleTest#14
                WEX::TestExecution::Examples::PictExample::SimpleTest#15
                WEX::TestExecution::Examples::PictExample::SimpleTest#16
                WEX::TestExecution::Examples::PictExample::SimpleTest#17
                WEX::TestExecution::Examples::PictExample::SimpleTest#18
                WEX::TestExecution::Examples::PictExample::SimpleTest#19
                WEX::TestExecution::Examples::PictExample::SimpleTest#20
                WEX::TestExecution::Examples::PictExample::SimpleTest#21
                WEX::TestExecution::Examples::PictExample::SimpleTest#22
                WEX::TestExecution::Examples::PictExample::SimpleTest#23

選択条件 (/select と /name) の詳細については、選択の Wiki ページを参照してください。

te Examples\Csharp.Pict.Example.dll /listproperties /select:"@Name='*SumofSquare*'
                    and @Data:index>10
Test Authoring and Execution Framework v2.9.3k for x86
        f:\ Examples\CSharp.Pict.Example.dll
            WEX.Examples.CSharpPictExample
                WEX.Examples.CSharpPictExample.SumOfSquareRoots#11
                        Property[DataSource] = pict:SumofSquareRoots.txt
                        Data[a] = 1
                        Data[b] = ~-1
                WEX.Examples.CSharpPictExample.SumOfSquareRoots#12
                        Property[DataSource] = pict:SumofSquareRoots.txt
                        Data[a] = 2
                        Data[b] = ~-1

上の例は、インデックスを使用して選択する方法を示しています。 データ値に基づいて選択することもできます。

te Examples\Csharp.Pict.Example.dll /listproperties /select:"@Name='*SumofSquare*'
                    and (@Data:A='1' and @Data:B='1')"
Test Authoring and Execution Framework v2.9.3k for x86
        f:\ Examples\CSharp.Pict.Example.dll
            WEX.Examples.CSharpPictExample
                WEX.Examples.CSharpPictExample.SumOfSquareRoots#8
                        Property[DataSource] = pict:SumofSquareRoots.txt
                        Data[a] = 1
                        Data[b] = 1

PICT 結果のキャッシュ

一部のモデル ファイルは非常に複雑になり、Pict.exe による処理に時間がかかる場合があります。 TAEF は、特定の Te.exe の実行中に結果をキャッシュすることで、結果の処理時間を軽減しようとします。 同じ実行の後続のテストで同じモデルとシード ファイルの組み合わせを参照する場合、TAEF はキャッシュされた結果を使用します。 既定では、各実行の最後に、キャッシュされた結果が削除されます。

後続の実行でキャッシュされた結果を引き続き利用する場合は、実行中にコマンド プロンプトで "/persistPictResults" オプションを指定します。 コマンドに "/persistPictResults" を指定すると、最初の実行では実際に pict.exe が実行されるため時間がかかることがありますが、後続のすべての実行では、モデル ファイルとシード ファイルが変更されていない場合、キャッシュされた結果が使用されます。 注: 後続の実行では、引き続き "/persistPictResults" を指定する必要があります。 後続の実行でこれを指定しない場合、その実行の最後にキャッシュされた結果が削除されます。

PICT の結果を保持し、キャッシュされたデータを既定で使用する場合は、次に示すように te_cmd 環境変数の一部として設定すれば、実行時に毎回指定する必要がなくなります。 te_cmd の詳細については、「テストの実行」を参照してください。

set te_cmd = /persistPictResults

キャッシュされた結果ファイルは、%temp% ディレクトリ内の "TAEF-PICT" という名前のフォルダーに格納されます (Te.exe がアクセスできる場合)。または Te.exe が起動された現在の実行ディレクトリに格納されます。 実行中に Ctrl + C キーを押した場合にのみ、結果が不整合な状態になる可能性があります。 このような場合、TAEF はキャッシュされた結果の削除を試みますが、削除できない場合は、その結果に対するエラーが表示されます。 このエラーでは、キャッシュされた結果の場所を削除するように求められます。 これを行わないと、後続のテストで未定義の動作または誤った動作が発生する可能性があります。

TAEF の組み込みの PICT サポートにより、テストの自動化で PICT の機能と TAEF の機能の両方を最大限に活用できるようになりました。

リソースとしての DataSource

PICT モデルを追加し、テスト モジュールでファイルをリソースとしてシード処理することができます。

ネイティブ コードでは、これは DataSource メタデータ内のファイル名ではなくリソース名を指定することによって行われます。 例を次に示します。

BEGIN_TEST_METHOD(ResourceNameDataSource)
    TEST_METHOD_PROPERTY(L"DataSource", L"Pict:MyModelResourceName?SeedingFile=MySeedingResourceName")
END_TEST_METHOD()

"MyModelResourceName" と "MySeedingResourceName" は、.rc ファイルで定義されているリソース名です。 リソースの種類が DATASOURCE_XML である必要があるテーブル データ ソースとは異なり、リソースの種類は DATAFILE である必要があります。

MyModelResourceName DATAFILE "model.txt"
MySeedingResourceName DATAFILE "seed.txt"

DataSource メタデータ値はモデルがファイルの場合と同じになります。 ネイティブ コードでも同様に、リソース名をファイル名と同じにすることができます。 TAEF はまず、DataSource 名を持つ実際のファイルの存在を探します。 ファイルが見つからない場合は、テスト モジュールのリソースを調べることで続行します。 リソースに格納されている DataSource を変更するには再コンパイルが必要であるため、この設計を活用するには、開発時に DataSource ファイルをテスト dll と同じ場所にコピーします (リソース名をファイル名と同じにします)。 テストが完了したら、ファイルをコード ディレクトリに移動し (コピーではない)、再コンパイルしてリソースを埋め込みます。