Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Jeśli automatyzacja testów opiera się na obecności urządzeń lub zasobów testowych, zapoznaj się z przykładem TestResourceExample i postępuj zgodnie z instrukcjami dotyczącymi korzystania z obsługi urządzeń lub obsługi zasobów testowych dostępnych w narzędziu TAEF. Przed kontynuowaniem upewnij się, że znasz sposób tworzenia podstawowych testów przy użyciu narzędzia TAEF i podstawowego wykonywania funkcji TAEF.
Tworzenie pod kątem obsługi urządzeń — plik źródła
Plik Te.Common.lib jest wymagany oprócz innych bibliotek potrzebnych do utworzenia testu w narzędziu TAEF.
Tworzenie pod kątem obsługi urządzeń — testowanie definicji zasobu
Użytkownicy są odpowiedzialni za tworzenie własnej definicji zasobu testowego (urządzenia). W tym celu należy zaimplementować usługę ITestResource. Element ITestResource jest zdefiniowany w opublikowanym pliku nagłówka ITestResource.h i wygląda następująco:
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*/
W naszym przykładzie klasa MyTestResource implementuje interfejs ITestResource COM. W pliku ITestResource.h znajduje się również lista zdefiniowanych właściwości, które są określone jako „must-have”. Powinno być możliwe uzyskanie identyfikatora GUID zasobu testowego przy użyciu metody GetGuid(..) oraz nazwy, identyfikatora i typu zasobu przy użyciu polecenia GetValue(...). Jeśli brakuje któregokolwiek z tych elementów w zasobie TestResource, TAEF uzna, że jest on nieprawidłowy i nie będzie przechowywać jego informacji. (Zobacz sekcję "Tworzenie listy zasobów", która znajduje się poniżej).
Tworzenie na potrzeby obsługi urządzeń — określanie metadanych zależnych od zasobu
Aby określić, że moduł testowy ma metody testowania zależne od zasobu, właściwość metadanych na poziomie modułu "TestResourceDependent" musi być ustawiona na wartość "true". Właściwość jest dziedziczona przez wszystkie klasy w module testowym i przez wszystkie metody testowe w tych klasach. Jeśli którakolwiek z metod testowych w module nie jest zależna od zasobu testowego, należy jawnie ustawić wartość metadanych na wartość false. Wszystkie inne metody testowe, które zależą od zasobu testowego, muszą dostarczyć zapytanie wyboru przy użyciu "Id" i/lub "Typ" zasobu testowego.
Oto kilka szybkich przykładów "ResourceSelection" dla naszej przykładowej listy zasobów i co każdy z nich oznacza:
- "@Id='HD*'": dopasuje każdy zasób z identyfikatorem rozpoczynającym się od "HD"
- "@Type='PCI'": pasuje do każdego zasobu typu "PCI"
- "@Id='PCI*' LUB @Id='HD*'": pasuje do każdego zasobu rozpoczynającego się od "PCI" lub rozpoczynającego się od "HD"
- "@Type='PCI' i @id='*37'": pasuje do każdego zasobu typu "PCI" z nazwą kończącą się na "37"
W naszym przykładowym kodzie wygląda to następująco:
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()
...
};
W powyższym przykładzie zobaczysz, że moduł jest oznaczony jako "TestResourceDependent". Test NoTestResourceTest jest jawnie oznaczony jako nie zależny od żadnego zasobu testowego, ustawiając metadane "TestRssourceDependent" na wartość "false". Wszystkie inne metody testowania określają kryteria wyboru dla zasobów testowych, dla których są zainteresowani wykonywaniem.
Gramatyka kryteriów wyboru jest bardzo podobna do gramatyki zapytań wiersza poleceń dostępnych w TAEF. Jednak w przypadku wyboru zasobu jest on ograniczony do używania identyfikatorów zasobów i typów. Ponieważ identyfikator zasobu jest ciągiem, należy go ująć w pojedynczy cudzysłów. Możesz używać symboli wieloznacznych "*" lub "?" przy wyznaczaniu wartości ID. W powyższym przykładzie w elemencie OneHDAudioTest wybór zasobów określa dopasowanie do dowolnego zasobu, którego identyfikator zaczyna się od "HD". Podobnie, w przypadku HDorPCITest wybór zasobu będzie zgodny z dowolnym zasobem, w którym identyfikator zaczyna się od "HD" lub zaczyna się od "PCI". Należy pamiętać, że wybór zasobu jest niewrażliwy na wielkość liter, czyli "pci", "Pci" i "PCI" będą traktowane identycznie.
Na podstawie wyboru zasobu TAEF ponownie wywoła metodę testową wraz z metodami konfiguracji i czyszczenia na poziomie testu (jeśli zostały określone), jednorazowo dla każdego zasobu testowego, który odpowiada wyborowi. W kolejnych sekcjach zostaną omówione szczegóły dotyczące sposobu określania listy zasobów i przekazywania jej do TAEF oraz tego, jak metoda testowa może pobierać zasoby opisane w następnej części.
Opracowywanie pod kątem obsługi urządzeń — tworzenie listy zasobów
Gdy tylko TAEF napotka moduł testowy TestResourceDependent, wyszuka i wywoła metodę eksportowaną przez DLL BuildResourceList. Jest to implementacja BuildResourceList, w ramach której użytkownicy mogą tworzyć nowe zasoby testowe i dodawać je do interfejsu, który jest przekazywany jako parametr do BuildResourceList. Przyjrzyjmy się implementacji tej metody w naszym przykładzie:
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 akceptuje odwołanie do PARAMETRu WEX::TestExecution::ResourceList. Element ResourceList jest zdefiniowany w opublikowanym pliku nagłówka ResourceList.h. Za pomocą metody Add(...) na liście ResourceList użytkownicy mogą dodawać wszystkie odnalezione lub utworzone zasoby testowe, aby taEF mogła zarządzać i pracować z nimi. W powyższym przykładzie dodano 5 takich zasobów testowych.
Metoda Add zakończy się niepowodzeniem, jeśli zasób testowy, który ma zostać dodany, nie zwróci "Name", "Id", "Type" lub GUID.
Lista zasobów będzie podtrzymywana przez cały okres trwania modułu testowego — czyli do momentu wykonania wszystkich metod testowych i metod sprzątania. Jeśli funkcja BuildResourceList zwraca wartość FAILED HRESULT, wszystkie metody testowe zależne od zasobów w module testowym są rejestrowane jako zablokowane bez wykonywania. Wszystkie zasoby inne niż testowe będą wykonywane niezależnie od tego.
Metoda BuildResourceList jest wywoływana przed wszelkimi innymi metodami w module testowym. Po utworzeniu listy zasobów (w funkcji BuildResourceList) metadane "ResourceSelection" są używane do dopasowania dostępnych zasobów na liście zasobów. W przypadku znalezienia dopasowania wszystkie metody instalacji (moduł, klasa, kolejność testów) są wywoływane przed samą metodą testową. Metoda czyszczenia poziomu testu jest wywoływana po każdorazowym uruchomieniu testu.
Za kulisami TAEF zachowuje listę zasobów, na której jest stosowany wybór zasobu. Na przykład w przypadku metody testowej OneHDAudioTest zasoby testowe o identyfikatorach "HDAudio-deviceid-1" i "HDAudio-deviceid-2" będą zgodne z wzorcem "HD*", a metoda testowa zostanie ponownie wywołana przez TAEF dla każdego z tych zasobów (raz dla każdego). Istnieje również niejawny indeks skojarzony z każdym wywołaniem testu. Więc zobaczysz <kwalifikator przestrzeni nazw OneHDAudioTest#0 i <kwalifikator przestrzeni nazw>>OneHDAudioTest#1 jako dwa wywołania.
Tworzenie pod kątem obsługi urządzeń — pobieranie urządzenia w metodzie testowej
W poprzednich sekcjach przedstawiono sposób dodawania niezbędnych metadanych na poziomie modułu, klasy i metody testowej. Przyjrzeli się również sposobom definiowania niestandardowych zasobów testowych i sposobu dodawania ich do listy ResourceList w implementacji buildResourceList. Następna część polega na pobieraniu zasobów w ramach metody testowej. Przyjrzyjmy się jednej z prostych metod testowania w naszym przykładzie:
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 }
W teście OneHDAudioTest, wybór zasobu polega na wybieraniu jednego zasobu testowego naraz, gdzie identyfikator zasobu zaczyna się od "HD". Statyczna klasa Resources zdefiniowana w pliku ResourceList.h udostępnia interfejsy API do pobierania liczby, a także rzeczywisty zasób dostępny podczas każdego wywołania testu. W tym przypadku, jak widać w wierszach 4, 9 i 13 w powyższym przykładzie, resources::Count() daje liczbę zasobów testowych dostępnych podczas bieżącego wywołania metody testowej. W tej metodzie testowej powinna to być wartość 1. Tę wartość można zweryfikować przy użyciu makr VERIFY, które są dostępne w narzędziu TAEF (Verify.h). Jak wiesz, jeśli którekolwiek z wywołań weryfikacji zakończy się niepowodzeniem w teście TAEF opartym na wyjątku, wykonanie zakończy się w tym momencie, a metoda testowa zostanie oznaczona jako Niepowodzenie.
Następnie użyj metody Resources::Item(...) z API, przekaż indeks, pod którym znajduje się zasób do pobrania (w tym przypadku, ponieważ podczas wywołania dostępny będzie tylko jeden zasób testowy, indeks zawsze będzie wynosić 0), aby pobrać zasób testowy. Metoda testowa może używać pobranego zasobu testowego w miarę potrzeb do testowania.
Ta sama podstawowa zasada jest przestrzegana we wszystkich metodach testowych. Przyjrzyj się innym metodom testowym w przykładzie, aby lepiej zrozumieć.
Wykonywanie modułu testowego zależnego od zasobu
Testy zależne od zasobów testowych są teraz tworzone i kompilowane, a teraz można je wykonać przy użyciu funkcji TAEF. Kluczową kwestią do zapamiętania jest to, że testy TestResourceDependent można wykonać tylko w trybie inproc. Oznacza to, że nawet jeśli nie określisz jawnie przełącznika "/inproc", zostanie on dodany, gdy TAEF odnajdzie moduł testowy zależny od zasobu testowego. Jak zapewne wiesz, można wykonać testy tylko z jednego modułu testowego w danym wykonaniu TAEF, gdy przełącznik "/inproc" jest obecny. Oznacza to, że nie można określić więcej niż jednego modułu testowego w wierszu polecenia, jeśli moduł testowy jest zależny od zasobu.
Aby faktycznie wykonać wszystkie testy w naszym module testowym, możesz po prostu uruchomić:
te Examples\Cpp.TestResource.Example.dll
Przydatnym sposobem uzyskania listy wszystkich wywołań metody testowej oraz kombinacji danych i metadanych bez faktycznego uruchamiania metod testowych jest użycie przełącznika /listproperties w wierszu polecenia. Przyjrzyjmy się wynikom.
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
Zwróć uwagę na niejawny indeks, który jest dodawany do nazwy metody testowej podczas każdego wywołania metody testowej uzależnionej od zasobu testowego. Po właściwości ResourceSelection zostanie wyświetlona lista wszystkich zasobów, które będą dostępne dla metody testowej w kolejności, w której będą dostępne. Na przykład w przypadku trzeciego wywołania HDAudioHDAudioPCITest (HDAudioHDAudioPCITest#2), HDAudio-deviceid-1 będzie zasobem dostępnym pod indeksem 0 w Resources::Item(...).
Możesz dokładniej określić, które wywołanie testowe cię interesuje, korzystając z języka zapytań selekcji dostępnego w narzędziu TAEF. Aby na przykład wybrać wszystkie wywołania metod testowych, w których dostępne są zasoby testowe "PCI-deviceid-3", można użyć kryteriów wyboru:
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
Podobnie, aby wybrać określoną metodę testową według nazwy (nazwy metod testowych są w pełni kwalifikowane wraz z indeksem wywołania dołączonym na końcu), można użyć zapytania wyboru w następujący sposób:
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
Zanotuj niejawne ostrzeżenie inproc dodane w trzecim wierszu powyższego przykładu. Powyższe zapytanie wyboru miało taki sam efekt jak zapytanie wyboru:/select:"@Name='*OneHDAudio*' And @Resource:Index=1". Można również wybrać zasób przy użyciu nazwy lub typu (lub identyfikatora, jak pokazano powyżej). Na przykład /select:"@Name='*PCIHDAudioTest*" i @Resource:Name="PCI3" wybierze metody testowe PCIHDAudioTest#4 i PCIHDAudioTest#5.
Wypróbowanie tych i innych zapytań wyboru w wierszu polecenia jest pozostawione jako ćwiczenie dla czytelnika.