次の方法で共有


デバイスのサポート

テストの自動化がデバイスまたはテスト リソースの存在に依存している場合は、TestResourceExample の例を参照し、TAEF で利用可能なデバイス サポートまたはテスト リソース サポートを活用する方法について説明します。 先に進む前に、TAEF を使用して基本テストを作成する方法と TAEF の基本的な実行について理解していることを確認してください。

デバイスサポート用の著作 ― ソースファイル

TE.Common.lib は、TAEF でテストを作成するために必要な他のライブラリに加えて必要です。

デバイスサポートのオーサリング - テストリソースの定義

ユーザーは、独自のテスト リソース (デバイス) 定義を作成する必要があります。 これを行うには、ITestResource を実装する必要があります。 ITestResource は、発行されたヘッダー ファイル ITestResource.h で定義され、次のようになります。

namespace WEX { namespace TestExecution
{
    namespace TestResourceProperty
    {
        // the following are reserved and must have properties for any TestResource definition
        static const wchar_t c_szName[] = L"Name";
        static const wchar_t c_szId[] = L"Id";
        static const wchar_t c_szGuid[] = L"GUID";
        static const wchar_t c_szType[] = L"Type";
    }

    struct __declspec(novtable) __declspec(uuid("79098e4c-b78d-434b-854d-2b59f5c4acc5")) ITestResource : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE GetGuid(GUID* pGuid) = 0;
        virtual HRESULT STDMETHODCALLTYPE SetGuid(GUID guid) = 0;
        virtual HRESULT STDMETHODCALLTYPE GetValue(BSTR name, BSTR* pValue) = 0;
        virtual HRESULT STDMETHODCALLTYPE SetValue(BSTR name, BSTR value) = 0;
    };
} /*namespace TestExecution*/ } /*namespace WEX*/

この例では、MyTestResource クラスは ITestResource COM インターフェイスを実装します。 ITestResource.h では、定義されている "must-have" プロパティの一覧も見つかります。 GetGuid(..) を使用してテスト リソースの GUID を取得し、GetValue(...) を使用してリソースの名前、ID、および型を取得できる必要があります。これが TestResource に存在しない場合、TAEF はそれを無効と見なし、情報を保持しません。(次の「リソースリストの作成」セクションを参照してください)。

デバイスサポートの作成—リソース依存メタデータの指定

テスト モジュールにテスト リソース依存のテスト メソッドがあることを指定するには、モジュール レベルのメタデータ プロパティ 'TestResourceDependent" を "true" に設定する必要があります。 このプロパティは、テスト モジュール内のすべてのクラスと、これらのクラス内のすべてのテスト メソッドによって継承されます。 モジュール内のいずれかのテスト メソッドがテスト リソースに依存していない場合は、メタデータ値を false に明示的に再設定する必要があります。 テスト リソースに依存する他のすべてのテスト メソッドでは、テスト リソースの "Id" または "Type" を使用して選択クエリを提供する必要があります。

この例のリソース リストの "ResourceSelection" の簡単なサンプルと、それぞれの意味を次に示します。

  • "@Id='HD*'": "HD" で始まる ID を持つ各リソースと一致します
  • "@Type='PCI'": 型 "PCI" の各リソースと一致します
  • "@Id='PCI*' OR @Id='HD*'": "PCI" または "HD" で始まる各リソースと一致します
  • "@Type='PCI' and @id='*37'": タイプが "PCI" で、名前が "37" で終わる各リソースに一致します。

このコード例では、これは次のようになります。

BEGIN_MODULE()
    MODULE_PROPERTY(L"TestResourceDependent", L"true")
END_MODULE()

    class TestResourceExample
    {
        TEST_CLASS(TestResourceExample);

        BEGIN_TEST_METHOD(NoTestResourceTest)
            TEST_METHOD_PROPERTY(L"TestResourceDependent", L"false")
        END_TEST_METHOD()

        BEGIN_TEST_METHOD(OneHDAudioTest)
            TEST_METHOD_PROPERTY(L"ResourceSelection", L"@Id='HD*'")
        END_TEST_METHOD()

        ...

        BEGIN_TEST_METHOD(HDorPCITest)
            TEST_METHOD_PROPERTY(L"ResourceSelection", L"@Id='PCI*' OR @Id='HD*'")
        END_TEST_METHOD()
        ...
    };

上記の例では、モジュールが "TestResourceDependent" としてマークされていることがわかります。 NoTestResourceTest は、"TestRssourceDependent" メタデータを "false" に設定することで、テスト リソースに依存しないと明示的にマークされます。 他のすべてのテスト メソッドは、実行対象のテスト リソースの選択条件を指定します。

選択基準文法は、TAEF で使用できるコマンド ライン選択クエリ文法によく似ています。 ただし、リソース選択の場合は、リソース ID と種類の使用に制限されます。 リソース ID は文字列であるため、単一引用符で囲む必要があります。 ID 値の指定では、ワイルドカード文字 "*" または "?" を使用できます。 上の例の OneHDAudioTest では、リソースの選択によって、ID が 'HD' で始まるリソースとの一致が指定されています。 同様に、HDorPCITest の場合、リソースの選択は、ID が 'HD' で始まるリソースまたは 'PCI' で始まるリソースと一致します。 リソースの選択では大文字と小文字が区別されません。つまり、"pci"、"Pci"、"PCI" はすべて同じように扱われます。

TAEF は、リソースの選択に基づいて、選択に一致する各テスト リソースについて、テスト レベルのセットアップとクリーンアップ メソッド (指定されている場合) と共にテスト メソッドを 1 回再呼び出します。 次のセクションでは、リソースの一覧を指定して TAEF に提供する方法と、テスト メソッドが次のセクションでリソースを取得する方法について詳しく説明します。

デバイスサポートのための作成 - リソースリストの作成

TAEF は TestResourceDependent テスト モジュールを検出するとすぐに、dll エクスポートメソッド BuildResourceList を探して呼び出します。 BuildResourceList の実装では、ユーザーは新しいテスト リソースを作成し、BuildResourceList にパラメーターとして渡されるインターフェイスに追加できます。 この例では、このメソッドの実装を見てみましょう。

using namespace WEX::TestExecution;
HRESULT __cdecl BuildResourceList(ResourceList& resourceList)
{
    Log::Comment(L"In BuildResourceList");

    GUID myGuid;
    VERIFY_SUCCEEDED(::CoCreateGuid(&myGuid));

    CComPtr<ITestResource> spTestResource;
    spTestResource.Attach(new MyTestResource(L"HDAudio1", L"HDAudio-deviceid-1", myGuid, L"HD"));
    resourceList.Add(spTestResource);

    spTestResource.Attach(new MyTestResource(L"HDAudio2", L"HDAudio-deviceid-2", myGuid, L"HD"));
    resourceList.Add(spTestResource);

    spTestResource.Attach(new MyTestResource(L"PCI1", L"PCI-deviceid-1", myGuid, L"PCI"));
    resourceList.Add(spTestResource);

    spTestResource.Attach(new MyTestResource(L"PCI2", L"PCI-deviceid-2", myGuid, L"PCI"));
    resourceList.Add(spTestResource);

    spTestResource.Attach(new MyTestResource(L"PCI3", L"PCI-deviceid-3", myGuid, L"PCI"));
    resourceList.Add(spTestResource);

    return S_OK;
}

BuildResourceList は、パラメーターとして WEX::TestExecution::ResourceList への参照を受け入れます。 ResourceList は、発行されたヘッダー ファイル ResourceList.h で定義されます。 ResourceList で Add(...) メソッドを使用すると、TAEF で検出または作成されたすべてのテスト リソースを追加して、管理および操作できます。 上記の例では、このようなテスト リソースを 5 つ追加しました。

追加するテスト リソースがリソースの "Name"、"Id"、"Type"、または GUID を返さなかった場合、Add メソッドは失敗します。

ResourceList は、テスト モジュールの有効期間を通じて維持されます。つまり、すべてのテスト メソッドとクリーンアップ メソッドの実行が完了するまでです。 BuildResourceList が FAILED HRESULT 値を返す場合、テスト モジュール内のすべてのリソース依存テスト メソッドは、実行せずにブロックとしてログに記録されます。 テスト以外のすべてのリソースは、関係なく実行されます。

BuildResourceList は、テスト モジュール内の他のメソッドの前に呼び出されます。 リソース リストがビルドされた後 (BuildResourceList 内)、"ResourceSelection" メタデータはリソース リスト内の使用可能なリソースと一致するために使用されます。 一致するものが見つかった場合、すべてのセットアップ メソッド (モジュール、クラス、テスト順序) が呼び出され、その後にテスト メソッド自体が呼び出されます。 テスト レベルのクリーンアップ メソッドは、各テスト呼び出しの後に呼び出されます。

バックグラウンドでは、TAEF はリソースの選択が適用される ResourceList を保持します。 たとえば、OneHDAudioTest テスト メソッドの場合、ID が "HDAudio-deviceid-1" と "HDAudio-deviceid-2" のテスト リソースはどちらも 'HD*' と一致し、これらのそれぞれに対して、テスト メソッドは TAEF によって再呼び出しされます (それぞれ 1 回)。 また、テストの各呼び出しに関連付けられた暗黙的なインデックスもあります。 そのため、 <namespace 修飾子>OneHDAudioTest#0 と <namespace 修飾子>OneHDAudioTest#1 が 2 つの呼び出しとして表示されます。

デバイスサポートのオーサリング - テストメソッドにおけるデバイスの取得

前のセクションでは、モジュール、クラス、およびテスト メソッド レベルで必要なメタデータを追加する方法について説明しました。 また、カスタム テスト リソースを定義する方法と、BuildResourceList の実装で ResourceList に追加する方法についても説明しました。 次のパートでは、テスト メソッド内のリソースを取得します。 この例の単純なテスト メソッドの 1 つを見てみましょう。

1   void TestResourceExample::OneHDAudioTest()
2   {
3       Log::Comment(L"In HD audio test");
4       size_t count = Resources::Count();
5       size_t index = 0;
6       VERIFY_ARE_EQUAL(count, (index + 1));
7
8       CComPtr<ITestResource> spTestResource;
9       VERIFY_SUCCEEDED(Resources::Item(index, &spTestResource));
10
11      // Get Resource Id
12      CComBSTR value;
13      VERIFY_SUCCEEDED(spTestResource->GetValue(CComBSTR(TestResourceProperty::c_szId), &value));
14      Log::Comment(L"Resource Id is " + String(value));
15  }

OneHDAudioTest では、リソースの選択によって、リソース ID が 'HD' で始まる一度に 1 つのテスト リソースが選択されます。 ResourceList.h で定義されている静的クラス Resources には、カウントを取得するための API と、特定のテストの呼び出し中に使用可能な実際のリソースが用意されています。 この場合、上の例の 4 行目、9 行目、13 行目でわかるように、Resources::Count() は、テスト メソッドの現在の呼び出し中に使用可能なテスト リソースの数を示します。 このテスト メソッドでは、これは 1 である必要があります。 この値は、TAEF (Verify.h) で使用できる VERIFY マクロを使用して確認できます。 ご存知のように、例外ベースの TAEF テストで検証呼び出しのいずれかが失敗した場合、実行はその時点で終了し、テスト メソッドは Failed としてマークされます。

次に、Resources::Item(...) を使用します。API を使用し、リソースを取得するインデックスを渡します (この場合、呼び出し中に使用できるテスト リソースは 1 つだけであるため、インデックスは常に 0 になります)。テスト リソースを取得できます。 テスト メソッドでは、取得したテスト リソースをテストに必要に応じてさらに使用できます。

すべてのテスト メソッドで同じ基本原則に従います。 この例の他のテスト メソッドを見て、理解を深めます。

テスト リソース依存テスト モジュールの実行

テスト リソース依存テストが作成され、ビルドされたので、TAEF を使用して実行できるようになりました。 重要な点は、TestResourceDependent テストは inproc でのみ実行できることです。 つまり、 "/inproc" スイッチを明示的に指定しない場合でも、TAEF がテスト リソース依存テスト モジュールを検出するとすぐに追加されます。 ご存知のように、"/inproc" スイッチが存在する場合、特定の TAEF 実行で実行できるテスト モジュールは 1 つだけです。 つまり、テスト モジュールがリソースに依存している場合は、コマンド ラインで複数のテスト モジュールを指定することはできません。

テスト モジュール内のすべてのテストを実際に実行するには、次のコマンドを実行します。

te Examples\Cpp.TestResource.Example.dll

テスト メソッドを実際に実行せずに、すべてのテスト メソッドの呼び出しとデータとメタデータの組み合わせの一覧を取得するだけの便利な方法は、コマンド ラインで /listproperties スイッチを使用することです。 出力を見てみましょう。

te Examples\Cpp.TestResource.Example.dll /listproperties

Test Authoring and Execution Framework v2.9.3k for x86
In BuildResourceList
Verify: SUCCEEDED(::CoCreateGuid(&myGuid))

        f:\toolsdev.binaries.x86chk\WexTest\CuE\TestExecution\Examples\Cpp.TestResource.Example.dll
                Property[TestResourceDependent] = true

            WEX::TestExecution::Examples::TestResourceExample
                WEX::TestExecution::Examples::TestResourceExample::NoTestResourceTest
                        Property[TestResourceDependent] = false

                WEX::TestExecution::Examples::TestResourceExample::OneHDAudioTest#0
                        Property[ResourceSelection] = @Id='HD*' 
                
                            Resource#0
                                Id = HDAudio-deviceid-1
                                Name = HDAudio1
                                Type = HD

                WEX::TestExecution::Examples::TestResourceExample::OneHDAudioTest#1
                        Property[ResourceSelection] = @Id='HD*'
                        
                            Resource#0
                                Id = HDAudio-deviceid-2
                                Name = HDAudio2
                                Type = HD

                WEX::TestExecution::Examples::TestResourceExample::OnePCIDeviceTest#0
                        Property[ResourceSelection] = @Id='PCI*'
                        
                            Resource#0
                                Id = PCI-deviceid-1
                                Name = PCI1
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::OnePCIDeviceTest#1
                        Property[ResourceSelection] = @Id='PCI*'
                        
                            Resource#0
                                Id = PCI-deviceid-2
                                Name = PCI2
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::OnePCIDeviceTest#2
                         Property[ResourceSelection] = @Id='PCI*'
                        
                            Resource#0
                                Id = PCI-deviceid-3
                                Name = PCI3
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#0
                        Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = HDAudio-deviceid-1
                                Name = HDAudio1
                                Type = HD

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#1
                         Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = HDAudio-deviceid-2
                                Name = HDAudio2
                                Type = HD

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#2
                         Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = PCI-deviceid-1
                                Name = PCI1
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#3
                         Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = PCI-deviceid-2
                                Name = PCI2
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#4
                         Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = PCI-deviceid-3
                                Name = PCI3
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::PCI1AudioTest #0
                         Property[ResourceSelection] = @Id='PCI*' AND @Id='*1'
                        
                            Resource#0
                                Id = PCI-deviceid-1
                                Name = PCI1
                                Type = PCI

テスト リソースの使用を必要とするテスト メソッドの各呼び出し中に、テスト メソッド名に追加される暗黙的なインデックスに注目してください。 ResourceSelection プロパティの後に、テスト メソッドで使用できるすべてのリソースの一覧が、使用可能な順序で表示されます。 たとえば、HDAudioHDAudioPCITest (HDAudioHDAudioPCITest#2) の 3 回目の呼び出しの場合、HDAudio-deviceid-1 は Resources::Item(...) のインデックス 0 で使用できるリソースになります。

TAEF で使用できるコマンド ライン選択クエリ言語を使用して、関心のあるテスト呼び出しをより具体的にすることができます。 たとえば、テスト リソース 'PCI-deviceid-3' が使用可能なテスト メソッドのすべての呼び出しを選択するには、選択条件を使用できます。

te Examples\Cpp.TestResource.Example.dll /list
          /select:"@Resource:Id='PCI-deviceid-3'"

Test Authoring and Execution Framework v2.9.3k for x86
In BuildResourceList
Verify: SUCCEEDED(::CoCreateGuid(&myGuid))

        f: \Examples\Cpp.TestResource.Example.dll
            WEX::TestExecution::Examples::TestResourceExample
                WEX::TestExecution::Examples::TestResourceExample::OnePCIDeviceTest#2
                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#4

同様に、特定のテスト メソッドを名前で選択するには (テスト メソッド名は末尾に追加された呼び出しインデックスと共に完全修飾されます)、次のように選択クエリを使用できます。

te Examples\Cpp.TestResource.Example.dll /name:*OneHDAudioTest#1
Test Authoring and Execution Framework v2.2 Build 6.1.7689.0 (release.091218-1251) for x86

Discovered a test resource dependent test module. Assuming /InProc execution.

In BuildResourceList
Verify: SUCCEEDED(::CoCreateGuid(&myGuid))

StartGroup: WEX::TestExecution::Examples::TestResourceExample::OneHDAudioTest#1
In HD audio test
Verify: AreEqual(count, (index + 1))
Verify: SUCCEEDED(Resources::Item(index, &spTestResource))
Verify: SUCCEEDED(spTestResource->GetValue(CComBSTR(TestResourceProperty::c_szId), &value))
Resource Id is HDAudio-deviceid-2
WEX::TestExecution::Examples::TestResourceExample::OneHDAudioTest#1 [Passed]

Summary: Total=1, Passed=1, Failed=0, Blocked=0, Not Run=0, Skipped=0

上記の例の 3 行目に暗黙的な inproc が追加された警告に注意してください。 上記の選択クエリは、選択クエリ:/select:"@Name='*OneHDAudio*' And @Resource:Index=1" と同じ効果を持っていました。 また、その名前または種類 (または上に示すように ID) を使用してリソースを選択することもできます。 たとえば、 /select:"@Name='*PCIHDAudioTest*' と @Resource:Name='PCI3'" は、PCIHDAudioTest#4 と PCIHDAudioTest#5 のテスト メソッドを選択します。

コマンド プロンプトでこれらのクエリやその他の選択クエリを試してみるのは、リーダーの演習として残されています。