Unterstützung für Geräte
Wenn Ihre Testautomatisierung auf das Vorhandensein von Geräten oder Testressourcen angewiesen ist, lesen Sie das Beispiel „TestResourceExample“, und befolgen Sie die Schritte, wie Sie die in TAEF verfügbare Geräteunterstützung oder Testressourcenunterstützung nutzen. Stellen Sie sicher, dass Sie mit dem Erstellen grundlegender Tests mit TAEF und der grundlegenden Ausführung von TAEF vertraut sind, bevor Sie fortfahren.
Erstellung der Geräteunterstützung – Quellendatei
Te.Common.lib ist zusätzlich zu anderen Bibliotheken erforderlich, um einen Test in TAEF zu erstellen.
Erstellung der Geräteunterstützung – Definition der Testressource
Benutzer sind für die Erstellung einer eigenen Testressourcendefinition (Gerät) verantwortlich. Dazu müssen Sie ITestResource implementieren. ITestResource ist in der veröffentlichten Headerdatei ITestResource.h definiert und sieht wie folgt aus:
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*/
In unserem Beispiel implementiert die Klasse MyTestResource die COM-Schnittstelle ITestResource. In ITestResource.h finden Sie auch eine Liste der definierten „must-have“-Eigenschaften. Es sollte möglich sein, die GUID für die Testressource mithilfe von GetGuid(.) und dem Namen, der ID und dem Typ der Ressource mithilfe von GetValue(...) abzurufen. Wenn eines dieser Elemente in einer TestResource fehlt, sieht TAEF sie als ungültig an und wird die Informationen nicht beibehalten.(Siehe Abschnitt „Erstellen der Ressourcenliste“.
Erstellung für die Geräteunterstützung – Angeben von ressourcenabhängigen Metadaten
Um anzugeben, dass das Testmodul über testressourcenabhängige Testmethoden verfügt, muss eine Metadateneigenschaft auf Modulebene von 'TestResourceDependent' auf „true“ festgelegt werden. Die Eigenschaft wird von allen Klassen im Testmodul und von allen Testmethoden in diesen Klassen geerbt. Wenn eine der Testmethoden im Modul nicht testressourcenabhängig ist, sollte es den Metadatenwert explizit auf „false“ zurückgesetzt werden. Alle anderen Testmethoden, die testressourcenabhängig sind, müssen eine Auswahlabfrage mithilfe der „ID“ und/oder „Type“ der Testressource bereitstellen.
Nachfolgend sehen Sie ein kurzes Beispiel für „ResourceSelection“ für unsere Beispielressourcenliste und was jede davon impliziert:
- "@Id='HD*'": entspricht jeder Ressource mit einer ID, die mit „HD“ beginnt.
- "@Type='PCI'": entspricht jeder Ressource vom Typ „PCI“
- "@Id='PCI*' ODER @Id='HD*'": entspricht jeder Ressource, die mit „PCI“ oder mit „HD“ beginnt.
- "@Type='PCI' und @id='*37'": entspricht jeder Ressource vom Typ „PCI“ mit einem Namen, der in „37“ endet.
In unserem Beispielcode sieht dies wie folgt aus:
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()
...
};
Im obigen Beispiel sehen Sie, dass das Modul als „TestResourceDependent“ gekennzeichnet ist. Der NoTestResourceTest wird explizit als nicht von einer Testressource abhängig markiert, indem „TestRssourceDependent“-Metadaten auf „false“ festgelegt werden. Alle anderen Testmethoden geben ein Auswahlkriterium für die Testressourcen an, für die sie ausgeführt werden sollen.
Die Grammatik der Auswahlkriterien ähnelt der Grammatik der Befehlszeilenauswahlabfrage, die für TAEF verfügbar ist. Im Falle der Ressourcenauswahl ist sie jedoch auf die Verwendung der Ressourcen-ID und -Typen beschränkt. Da es sich bei der Ressourcen-ID um eine Zeichenfolge handelt, muss sie in einfache Anführungszeichen eingeschlossen werden. Sie können die Wildcardzeichen „*“ oder „?“ in der Spezifikation des ID-Werts verwenden. In unserem obigen Beispiel in OneHDAudioTest gibt die Ressourcenauswahl eine Übereinstimmung mit jeder Ressource an, in der die ID mit „HD“ beginnt. Ebenso entspricht die Ressourcenauswahl im Falle von HDorPCITest jeder Ressource, in der die ID mit „HD“ beginnt oder mit „PCI“ beginnt. Es ist wichtig zu beachten, dass bei der Ressourcenauswahl die Groß-/Kleinschreibung nicht beachtet wird – d. h. „pci“, „Pci“ und „PCI“ werden alle gleich behandelt.
Basierend auf der Ressourcenauswahl ruft TAEF die Testmethode zusammen mit den Setup- und Bereinigungsmethoden auf Testebene (sofern angegeben) einmal für jede Testressource erneut auf, die der Auswahl entspricht. In den folgenden Abschnitten werden die Details zum Angeben der Liste der Ressourcen und die Bereitstellung an TAEF und die Art und Weise, wie die Testmethode die Ressourcen im nächsten Abschnitt abrufen kann, untersucht.
Erstellung der Geräteunterstützung – Erstellen der Ressourcenliste
Sobald TAEF auf ein TestResourceDependent-Testmodul trifft, sucht und ruft die dll-exportierte Methode BuildResourceList auf. In der Implementierung von BuildResourceList können Benutzer neue Testressourcen erstellen und sie der Schnittstelle hinzufügen, die als Parameter an BuildResourceList übergeben wird. Sehen wir uns die Implementierung dieser Methode in unserem Beispiel an:
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 akzeptiert einen Verweis auf WEX::TestExecution::ResourceList als Parameter. ResourceList ist in der veröffentlichten Headerdatei ResourceList.h definiert. Mithilfe der Add(...)-Methode auf der ResourceList können Benutzer alle ermittelten oder für TAEF erstellten Testressourcen hinzufügen, um sie zu verwalten und zu verwenden. Im obigen Beispiel wurden 5 solche Testressourcen hinzugefügt.
Die Add-Methode schlägt fehl, wenn die hinzuzufügende Testressource den Fehler „Name“, „ID“, „Type“ oder GUID für die Ressource zurückgibt.
Die ResourceList wird über die Lebensdauer des Testmoduls verwaltet, d. h., bis alle Testmethoden und Bereinigungsmethoden ausgeführt werden. Wenn BuildResourceList einen FAILED HRESULT-Wert zurückgibt, werden alle ressourcenabhängigen Testmethoden im Testmodul als blockiert protokolliert, ohne ausgeführt zu werden. Alle nicht-Test-Ressourcen werden unabhängig davon ausgeführt.
BuildResourceList wird vor allen anderen Methoden im Testmodul aufgerufen. Nachdem die Ressourcenliste erstellt wurde (in BuildResourceList), werden die ResourceSelection-Metadaten verwendet, um die verfügbaren Ressourcen in der Ressourcenliste abzugleichen. Wenn eine Übereinstimmung gefunden wird, werden alle Einrichtungsmethoden (Modul, Klasse, Testreihenfolge) aufgerufen, gefolgt von der Testmethode selbst. Die Bereinigungsmethode auf Testebene wird nach jedem Testaufruf aufgerufen.
Im Hintergrund behält TAEF die ResourceList bei, auf die die Ressourcenauswahl angewendet wird. Bei der OneHDAudioTest-Testmethode stimmen beispielsweise die Testressourcen mit den IDs „HDAudio-deviceid-1“ und „HDAudio-deviceid-2“ beide mit „HD*“ überein, und für jede davon wird die Testmethode von TAEF erneut aufgerufen (jeweils einmal). Es wird auch ein impliziter Index vorhanden sein, der jedem Aufruf des Tests zugeordnet ist. Daher sehen Sie den <Namespacequalifizierer>OneHDAudioTest#0 und den <Namespacequalifizierer>OneHDAudioTest#1 als die beiden Aufrufe.
Erstellung der Geräteunterstützung – Abrufen des Geräts in einer Testmethode
In den vorherigen Abschnitten wurde erläutert, wie Sie die erforderlichen Metadaten auf Modul-, Klassen- und Testmethodenebene hinzufügen. Außerdem haben sie untersucht, wie benutzerdefinierte Testressourcen definiert werden und wie sie der ResourceList in der Implementierung von BuildResourceList hinzugefügt werden. Der folgende Abschnitt behandelt das Abrufen der Ressourcen in der Testmethode. Sehen wir uns eine der einfachen Testmethoden in unserem Beispiel an:
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 }
In OneHDAudioTest wählt die Ressourcenauswahl jeweils eine Testressource aus, bei der die Ressourcen-ID mit „HD“ beginnt. Die in ResourceList.h definierten Ressourcen der statischen Klasse stellen die APIs zum Abrufen der Anzahl sowie der tatsächlichen Ressource bereit, die während eines bestimmten Aufrufs des Tests verfügbar ist. Wie in den Zeilen 4, 9 und 13 im obigen Beispiel zu sehen ist, gibt Resources::Count() die Anzahl der verfügbaren Testressourcen während des aktuellen Aufrufs der Testmethode an. Bei dieser Testmethode sollte dies 1 sein. Sie können diesen Wert mithilfe der VERIFY-Makros verifizieren, die in TAEF (Verify.h) verfügbar sind. Wie Sie wissen, wird die Ausführung an diesem Punkt beendet, wenn einer der Überprüfungsaufrufe in einem ausnahmebasierten TAEF-Test fehlschlägt, und die Testmethode wird als fehlgeschlagen markiert.
Als Nächstes können Sie mit Hilfe von Resources::Item(...) API und der Übergabe eines Indexes, an welchem die Ressource abgerufen werden soll (da in diesem Fall nur eine Testressource während des Aufrufs verfügbar ist, wird der Index immer 0 sein), die Testressource abrufen. Die Testmethode kann die abgerufene Testressource weiter verwenden, da sie für ihre Tests benötigt wird.
Das gleiche Grundprinzip wird in allen Testmethoden befolgt. Sehen Sie sich andere Testmethoden im Beispiel an, um dies besser zu verstehen.
Ausführen eines testressourcenabhängigen Testmoduls
Nachdem die testressourcenabhängigen Tests jetzt erstellt wurden, können Sie sie jetzt mit TAEF ausführen. Der wichtigste Punkt ist, dass TestResourceDependent-Tests nur inproc ausgeführt werden können. Dies bedeutet, dass auch wenn Sie den Schalter "/inproc" nicht explizit angeben, er hinzugefügt wird, sobald TAEF das testressourcenabhängige Testmodul ermittelt. Wie Sie wissen, können Tests von nur einem Testmodul in einer bestimmten TAEF-Ausführung ausgeführt werden, wenn der Schalter "/inproc" vorhanden ist. Dies bedeutet, dass Sie nicht mehr als ein Testmodul in der Befehlszeile angeben können, wenn Ihr Testmodul ressourcenabhängig ist.
Um tatsächlich alle Tests in unserem Testmodul auszuführen, können Sie einfach folgendes ausführen:
te Examples\Cpp.TestResource.Example.dll
Eine nützliche Möglichkeit, nur eine Auflistung aller Aufrufe der Testmethode und die Daten- und Metadatenkombinationen zu erhalten, ohne die Testmethoden tatsächlich auszuführen, besteht darin, den Schalter "/listproperties" in der Befehlszeile zu verwenden. Sehen wir uns die Ausgabe an.
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
Beachten Sie den impliziten Index, der während jedes Aufrufs einer testressourcenabhängigen Testressource zum Namen der Testmethode hinzugefügt wird. Die ResourceSelection-Eigenschaft wird gefolgt von einer Liste aller Ressourcen angezeigt, die für die Testmethode verfügbar sind, in der Reihenfolge in der sie verfügbar werden. Bei dem dritten Aufruf von HDAudioHDAudioPCITest (HDAudioHDAudioPCITest#2) ist HDAudio-deviceid-1 beispielsweise die Ressource, die unter Index 0 in Resources::Item(...) verfügbar ist.
Sie können spezifischer sein, an welchem Testaufruf Sie interessiert sind, indem Sie die in TAEF verfügbare Befehlszeilenauswahlabfragesprache verwenden. Um beispielsweise alle Aufrufe von Testmethoden auszuwählen, bei denen die Testressourcen „PCI-deviceid-3“ verfügbar sind, können Sie diese Auswahlkriterien verwenden:
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
Ebenso können Sie eine Auswahlabfrage wie folgt verwenden, um eine bestimmte Testmethode anhand des Namens auszuwählen (beachten Sie, dass Testmethodennamen zusammen mit dem am Ende angefügten Aufrufindex vollständig qualifiziert werden):
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
Beachten Sie die implizite Inproc-Warnung in der dritten Zeile des obigen Beispiels. Die obige Auswahlabfrage hat die gleiche Wirkung wie die Auswahlabfrage:/select:"@Name='*OneHDAudio*' And @Resource:Index=1". Es ist auch möglich, eine Ressource mithilfe des Namens oder Typs (oder der ID wie oben dargestellt) auszuwählen. Beispielsweise wählt /select:"@Name='*PCIHDAudioTest*' und @Resource:Name='PCI3'" die Testmethoden PCIHDAudioTest#4 und PCIHDAudioTest#5 aus.
Das Ausprobieren dieser und anderer Auswahlabfragen an der Eingabeaufforderung bleibt dem Leser als Übung überlassen.