Sdílet prostřednictvím


Podpora zařízení

Pokud vaše automatizace testů spoléhá na přítomnost zařízení nebo testovacích prostředků, projděte si příklad TestResourceExample a postupujte podle pokynů, jak využít podporu zařízení nebo testovací prostředky dostupné v TAEF. Než budete pokračovat, ujistěte se, že jste obeznámeni s vytvářením základních testů pomocí taEF a základního provádění funkce TAEF.

Vytváření obsahu pro podporu zařízení – soubor zdroje

Kromě dalších knihoven, které potřebují vytvořit test v taEF, je potřeba Te.Common.lib.

Vytváření obsahu pro podporu zařízení – definice testovacího prostředku

Uživatelé zodpovídají za vytvoření vlastní definice testovacího prostředku (zařízení). K tomu je potřeba implementovat ITestResource. ITestResource je definován v publikovaném souboru hlaviček ITestResource.h a vypadá takto:

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*/

V našem příkladu třída MyTestResource implementuje COM rozhraní ITestResource. V souboru ITestResource.h najdete také seznam definovaných vlastností "must-have". Identifikátor GUID testovacího prostředku by měl být možné získat pomocí GetGuid(..) a názvu, ID a typu prostředku pomocí GetValue(...). Pokud některá z těchto možností v TestResource chybí, taEF ji považuje za neplatnou a neudržuje informace. (Viz část "Sestavení seznamu zdrojů", která následuje).

Vytváření pro podporu zařízení – Specifikace metadat závislých na prostředcích

Aby bylo možné určit, že testovací modul má testovací metody závislé na prostředcích, musí být vlastnost metadat na úrovni modulu TestResourceDependent nastavena na hodnotu true. Vlastnost je zděděna všemi třídami v testovacím modulu a všemi testovacími metodami v těchto třídách. Pokud některá z testovacích metod v modulu není závislá na testovacím prostředku, měla by explicitně znovu nastavit hodnotu metadat na false. Všechny ostatní testovací metody, které závisí na testovacím prostředku, musí poskytnout výběrový dotaz s použitím "ID" a/nebo "Type" testovacího prostředku.

Tady je několik rychlých ukázek ResourceSelection pro náš ukázkový seznam prostředků a to, co každý z nich znamená:

  • "@Id='HD*'": odpovídá jednotlivým prostředkům s Id začínajícím na "HD".
  • "@Type='PCI": odpovídá každému prostředku typu "PCI"
  • "@Id='PCI*' OR @Id='HD*'": odpovídá každému prostředku začínajícímu na "PCI" nebo "HD".
  • "@Type='PCI' a @id='*37'": odpovídá každému prostředku typu "PCI" s názvem končícím na "37".

V našem ukázkovém kódu to vypadá takto:

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()
        ...
    };

V předchozím příkladu uvidíte, že je modul označený jako TestResourceDependent. NoTestResourceTest je explicitně označen jako nespoléhavý na žádném testovacím prostředku nastavením metadat TestRssourceDependent na false. Všechny ostatní testovací metody stanovují kritéria výběru pro testovací prostředky, které chtějí provést.

Gramatika kritérií výběru je velmi podobná gramatikě výběrového dotazu příkazového řádku, která je k dispozici pro TAEF. V případě výběru prostředku je však omezeno na použití ID a typů prostředku. Vzhledem k tomu, že ID prostředku je řetězec, musí být uzavřen v jednoduchých uvozovkách. Ve specifikaci hodnoty ID můžete použít zástupné znaky "*" nebo "?". V našem příkladu výše určuje výběr prostředku v OneHDAudioTest shodu s jakýmkoli prostředkem, kde ID začíná písmeny "HD". Podobně v případě HDorPCITest bude výběr prostředků odpovídat jakémukoli prostředku, kde ID začíná na "HD" nebo začíná na "PCI". Je důležité si uvědomit, že výběr prostředků nerozlišuje velká a malá písmena – to znamená, že pci, Pci a PCI budou považovány za stejné.

Na základě výběru prostředků taEF znovu vyvolá testovací metodu spolu s nastavením na úrovni testu a metodami čištění (pokud jsou zadány) jednou pro každý testovací prostředek, který odpovídá výběru. V následujících částech se podíváme na podrobnosti o tom, jak určit seznam prostředků a poskytnout ho taEF a jak testovací metoda může načíst prostředky v další části.

Vytváření obsahu pro podporu zařízení – Vytvoření seznamu prostředků

Jakmile TAEF narazí na TestResourceDependent testovací modul, vyhledá a vyvolá dll-exportovanou metodu BuildResourceList. Je v implementaci BuildResourceList, kde uživatelé mohou vytvořit nové testovací prostředky a přidat je do rozhraní, které se předá jako parametr BuildResourceList. Podívejme se na implementaci této metody v našem příkladu:

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 přijímá jako parametr odkaz na WEX::TestExecution::ResourceList. ResourceList je definován v publikovaném souboru hlaviček ResourceList.h. Pomocí metody Add(...) na ResourceList mohou uživatelé přidat všechny zjištěné nebo vytvořené testovací prostředky pro TAEF pro správu a práci s ní. Výše uvedený příklad přidal 5 takových testovacích prostředků.

Metoda Add selže, pokud testovací prostředek, který se má přidat, nevrátí buď "Název", "ID", "Typ" nebo GUID prostředku.

ResourceList se bude udržovat po celou dobu životnosti testovacího modulu – to znamená až do provedení všech testovacích metod a metod vyčištění. Pokud BuildResourceList vrátí hodnotu FAILED HRESULT, všechny testovací metody závislé na prostředcích v testovacím modulu se protokolují jako blokované bez spuštění. Všechny netestované prostředky se spustí bez ohledu na to.

BuildResourceList je vyvolán před všemi jinými metodami v testovacím modulu. Po sestavení seznamu prostředků (v procesu BuildResourceList) se metadata ResourceSelection použijí k porovnání dostupných prostředků v seznamu prostředků. Pokud je nalezena shoda, jsou vyvolány všechny metody nastavení (modul, třída, pořadí testů) následované samotnou testovací metodou. Metoda vyčištění na úrovni testu se volá po každém vyvolání testu.

TAEF na pozadí uchovává ResourceList, na kterém se použije výběr prostředku. Například pro metodu testu OneHDAudioTest budou testovací zdroje s ID "HDAudio-deviceid-1" a "HDAudio-deviceid-2" odpovídat "HD*" a pro každý z nich bude metoda testu znovu vyvolána TAEF (jednou pro každý). K každému vyvolání testu bude přidružený také implicitní index. Zobrazí se <tedy kvalifikátor>oboru názvů OneHDAudioTest#0 a <kvalifikátor>oboru názvů OneHDAudioTest#1 jako dvě vyvolání.

Vytváření obsahu pro podporu zařízení – Načtení zařízení v testovací metodě

Předchozí části se podívaly na to, jak přidat potřebná metadata na úrovni modulu, třídy a testovací metody. Také se podívali, jak definovat vlastní testovací prostředky a jak je přidat do ResourceList v implementaci BuildResourceList. Následující část načítá zdroje v testovací metodě. Podívejme se na jednu z jednoduchých testovacích metod v našem příkladu:

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  }

V OneHDAudioTest výběr prostředku vybere jeden testovací prostředek v okamžiku, kdy ID prostředku začíná na "HD". Statická třída Resources, definovaná v ResourceList.h, poskytuje rozhraní API pro načtení počtu i skutečného prostředku dostupného během jakéhokoli vyvolání testu. V tomto případě, jak vidíte na řádcích 4, 9 a 13 v příkladu výše, Resources::Count() poskytuje počet testovacích prostředků dostupných během aktuálního vyvolání testovací metody. V této testovací metodě by to mělo být 1. Tuto hodnotu můžete ověřit pomocí maker VERIFY, která jsou k dispozici v TAEF (Verify.h). Jak víte, pokud některé z ověřovacích volání selže v testu TAEF založeném na výjimkách, provádění se v tomto okamžiku ukončí a testovací metoda by byla označena jako neprovedena.

Dále pomocí rozhraní API Resources::Item(...) a zadáním indexu, na kterém se má prostředek načíst (v tomto případě, protože během vyvolání bude k dispozici pouze jeden testovací prostředek, bude index vždy 0), můžete testovací prostředek načíst. Testovací metoda může dále používat načtený testovací prostředek, protože potřebuje pro jeho testování.

Stejný základní princip se dodržuje ve všech testovacích metodách. Podívejte se na další testovací metody v příkladu, abyste lépe porozuměli.

Spuštění testovacího modulu závislého na zdrojích

Když jsou testy závislé na testovacích prostředcích napsané a zkompilované, můžete je nyní spouštět pomocí TAEF. Klíčovým bodem je, že testy TestResourceDependent lze provádět pouze inproc. To znamená, že i když explicitně nezadáte přepínač /inproc, přidá se hned poté, co TAEF zjistí testový modul závislý na testovacím prostředku. Jak můžete vědět, testy pouze z jednoho testovacího modulu se dají spouštět v daném provedení TAEF, když je k dispozici přepínač /inproc. To znamená, že na příkazovém řádku nemůžete zadat více než jeden testovací modul, pokud je testovací modul závislý na prostředku.

Pokud chcete skutečně provést všechny testy v našem testovacím modulu, můžete jednoduše spustit:

te Examples\Cpp.TestResource.Example.dll

Užitečný způsob, jak jednoduše získat výpis všech vyvolání testovací metody a kombinace dat a metadat bez skutečného spuštění testovacích metod, je použít přepínač /listproperties na příkazovém řádku. Podívejme se na výstup.

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

Všimněte si implicitního indexu, který se přidá do názvu testovací metody během každého vyvolání testovací metody vyřazení testovacího prostředku. Vlastnost ResourceSelection se zobrazí a následuje seznam všech prostředků, které budou k dispozici pro testovací metodu v pořadí, ve kterém budou k dispozici. U třetího vyvolání HDAudioHDAudioPCITest (HDAudioHDAudioPCITest#2) bude HDAudio-deviceid-1 zdrojem dostupným na indexu 0 v Resources::Item(...).

Pomocí dotazovacího jazyka příkazového řádku, který je k dispozici v TAEF, můžete konkrétněji určit, které vyvolání testů vás zajímá. Pokud například chcete vybrat všechna vyvolání testovacích metod, kde jsou k dispozici testovací prostředky PCI-deviceid-3, můžete použít kritéria výběru:

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

Podobně pokud chcete vybrat konkrétní testovací metodu podle názvu (všimněte si, že názvy testovacích metod jsou plně kvalifikované spolu s indexem vyvolání připojeným na konci), můžete použít výběrový dotaz následujícím způsobem:

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

Všimněte si implicitního upozornění přidaného v třetím řádku výše uvedeného příkladu. Výše uvedený dotaz výběru měl stejný účinek jako dotaz výběru:/select:"@Name='*OneHDAudio*' And @Resource:Index=1". Prostředek je také možné vybrat pomocí jeho názvu nebo typu (nebo ID, jak je znázorněno výše). Například /select:"@Name='*PCIHDAudioTest*' a @Resource:Name='PCI3'" vybere testovací metody PCIHDAudioTest#4 a PCIHDAudioTest#5.

Vyzkoušení těchto a dalších výběrových dotazů na příkazovém řádku je ponecháno jako cvičení pro čtenáře.