如果您的測試自動化依賴裝置或測試資源的存在,請參閱範例 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*'”:比對每個 ID 以 “HD” 開頭的資源
- “@Type='PCI'”:符合類型為 “PCI” 的每個資源
- “@Id='PCI*' OR @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」。 將 “TestRssourceDependent” 中繼資料設定為 “false”,將 NoTestResourceTest 明確標示為不相依於任何測試資源。 所有其他測試方法都會指定它們有興趣執行的測試資源的選取準則。
選取準則文法與 TAEF 可用的命令列選取查詢文法非常類似。 不過,在資源選取的情況下,它僅限於使用資源標識碼和類型。 由於資源 ID 是 String,因此需要用單引號括起來。 您可以在 Id 值的規格中使用萬用字元 “*” 或 “?” 。 在上述範例中,在 OneHDAudioTest 中,資源選取範圍會指定與 Id 以 'HD' 開頭的任何資源相符。 同樣地,在 HDorPCITest 的情況下,資源選取範圍會符合 Id 以 '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 個這樣的測試資源。
如果要新增的測試資源無法傳回資源的 “Name”、“Id”、“Type” 或 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 測試只能在程序內執行。 這表示即使您未明確指定 「/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 (HDAudioHDAudioPCITest#2) ,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
請注意,在上述範例的第三行中新增了隱含的 inproc 警告。 上述選擇查詢與選擇查詢的效果相同:/select:“@Name='*OneHDAudio*' 和 @Resource:Index=1”。 您也可以使用資源的名稱或類型 (或如上所示的 ID) 來選取資源。 例如, /select:“@Name='*PCIHDAudioTest*' 和 @Resource:Name='PCI3'” 會選取測試方法 PCIHDAudioTest#4 和 PCIHDAudioTest#5。
在命令提示字元中嘗試這些和其他選取查詢,留給讀者做練習。