共用方式為


裝置支援

如果您的測試自動化仰賴裝置或測試資源的存在,請參閱範例 TestResourceExample,並遵循如何利用 TAEF 中提供的裝置支援或測試資源支援。 請先確定您已熟悉如何使用TAEF撰寫基本測試,以及TAEF的基本執行,再繼續進行。

撰寫裝置支援 - 來源檔案

除了在 TAEF 中撰寫測試所需的其他連結庫之外,還需要 Te.Common.lib。

裝置支援的撰寫 - 測試資源定義

用戶須負責建立自己的測試資源(裝置)定義。 若要這樣做,您必須實作 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 中,您也會找到已定義的「必須擁有」屬性清單。 應該可以使用 GetGuid(..) 取得測試資源的 GUID,以及使用 GetValue(...) 取得資源的名稱、識別碼和類型。如果 TestResource 中遺漏任何一項,TAEF 會將其視為無效,而不會維護其資訊。(請參閱下列一節。

撰寫裝置支援 - 指定資源相依元數據

若要指定測試模組具有測試資源相依測試方法,必須將模組層級元數據屬性 『TestResourceDependent」 設定為 「true」。 屬性會由測試模組中的所有類別以及這些類別中的所有測試方法繼承。 如果模組中的任何測試方法與測試資源無關,則應該明確地將元數據值重新設定為 false。 相依於測試資源的其他所有測試方法都必須使用測試資源的 「標識碼」和/或「類型」來提供選取查詢。

以下是範例資源清單的一些快速範例 「ResourceSelection」,以及每個範例所暗示的內容:

  • “@Id='HD*'”:比對每個資源,標識符開頭為 “HD”
  • “@Type='PCI'”:符合類型 “PCI” 的每個資源
  • “@Id='PCI*' 或 @Id='HD*'”:比對以 “PCI” 開頭或以 “HD” 開頭的每個資源
  • “@Type='PCI' 和 @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可用的命令行選取查詢文法非常類似。 不過,在資源選取的情況下,它僅限於使用資源標識碼的和類型。 由於資源標識碼是 String,因此必須以單引弧括住。 您可以在識別碼值的規格中使用通配符 「*」 或 「?“ 」。 在上述範例中,在 OneHDAudioTest 中,資源選取範圍會指定與標識碼以 『HD』 開頭的任何資源相符。 同樣地,在 HDorPCITest 的情況下,資源選取專案會比對標識符開頭為 『HD』 或開頭為 『PCI』 的任何資源。 請務必注意,資源選取專案不區分大小寫,也就是說,「pci」、「Pci」和「PCI」都會以相同方式處理。

根據資源選取範圍,TAEF 會針對符合選取專案的每個測試資源重新叫用測試方法,以及測試層級設定和清除方法(如果已指定的話)。 下列各節將檢查如何指定資源清單的詳細數據,並將其提供給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個這類測試資源。

如果要加入的測試資源無法傳回資源的 「名稱」、「標識元」、「類型」或 GUID,則 Add 方法將會失敗。

ResourceList 將會在測試模組的存留期內維護,也就是執行所有測試方法和清除方法為止。 如果 BuildResourceList 傳回 FAILED HRESULT 值,測試模組中的所有資源相依測試方法都會記錄為封鎖而不執行。 不論是否執行所有非測試資源。

BuildResourceList 會在測試模組的任何其他方法之前叫用。 建置資源清單之後(在 BuildResourceList 中),“ResourceSelection” 元數據會用來比對資源清單中的可用資源。 如果找到相符專案,則會叫用所有安裝方法(模組、類別、測試順序),後面接著測試方法本身。 測試層級清除方法會在每次測試調用之後呼叫。

在幕後,TAEF 會保留套用資源選取範圍的 ResourceList。 例如,針對 OneHDAudioTest 測試方法,標識符為 “HDAudio-deviceid-1” 和 “HDAudio-deviceid-2” 的測試資源會比對 'HD*' 和其中每一個,則測試方法會由 TAEF 重新叫用(一次用於每個)。 也會有與測試每個叫用相關聯的隱含索引。 因此,您會看到 <命名空間限定符>OneHDAudioTest#0 和 <命名空間限定符>OneHDAudioTest#1 作為兩個調用。

撰寫裝置支援 - 在測試方法中擷取裝置

上一節探討如何在模組、類別和測試方法層級新增必要的元數據。 他們還探討如何定義自定義測試資源,以及如何在 BuildResourceList 的實作中將其新增至 ResourceList。 接下來的下一個部分是擷取測試方法中的資源。 讓我們看看範例中的其中一個簡單測試方法:

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 中,資源選取專案會一次選取一個測試資源,其中資源標識符以 『HD』 開頭。 在 ResourceList.h 中定義的靜態類別 Resources 會提供 API 來擷取計數,以及在測試的任何指定叫用期間可用的實際資源。 在此情況下,如您在上述範例中的第 4、9 和 13 行中所見,Resources::Count() 提供測試方法目前調用期間可用的測試資源計數。 在此測試方法中,這應該是 1。 您可以使用 TAEF (Verify.h) 中可用的 VERIFY 宏來驗證此值。 如您所知,如果任何驗證呼叫在例外狀況型 TAEF 測試中失敗,執行將會在該時間點終止,而且測試方法會標示為失敗。

接下來,使用 Resources::Item(...)API 並傳入要擷取資源的索引(在此情況下,由於叫用期間只能有一個測試資源可用,索引一律為0),因此您可以擷取測試資源。 測試方法可以進一步使用擷取的測試資源,因為它需要測試。

所有測試方法都會遵循相同的基本原則。 請查看範例中的其他測試方法,以取得更好的瞭解。

執行測試資源相依測試模組

現在,藉由撰寫和建置測試資源相依測試,您現在可以使用TAEF加以執行。 要注意的重點是,TestResourceDependent 測試只能在proc 中執行。 這表示即使您未明確指定 「/inproc」 參數,在TAEF探索測試資源相依測試模組時,也會立即新增。 如您所知,當 「/inproc」 參數存在時,只有一個測試模組的測試可以在指定的 TAEF 執行中執行。 這表示如果您的測試模組相依於資源,則無法在命令行指定多個測試模組。

若要實際執行測試模組中的所有測試,您可以直接執行:

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 的第三次叫用(HDAudioHDAudioHDAudioPCITest#2),HDAudio-deviceid-1 將是 Resource::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

請注意上述範例第三行的隱含 inproc 新增警告。 上述選取範圍查詢的效果與選取查詢:/select:“@Name='*OneHDAudio*' And @Resource:Index=1”相同。 您也可以使用資源的名稱或類型來選取資源(或標識符,如上所示)。 例如, /select:“@Name='*PCIHDAudioTest*' 和 @Resource:Name='PCI3'” 會選取測試方法 PCIHDAudioTest#4 和 PCIHDAudioTest#5。

在命令提示字元嘗試這些和其他選取查詢時,會保留為讀者的練習。