請確定您熟悉 TAEF 的基本執行,並知道如何使用它來撰寫測試,再繼續本節。
PICT 背景和參考文獻
PICT 代表成對獨立組合測試。 PICT 可讓您個別指定每個參數的變化。 例如,如果 API 測試相依於兩個參數:FileName 和 FileExtension,您可以考慮要分別傳遞 FileName 和 FileExtensions 的可能變化,如下所示:
- 檔案名稱:a,z12390,Realllyreallyreallylonglonglonglonglonglonglonglonglonglong,normallength
- 檔案副檔名: txt、png、bat、doc、exe、bmp、wav
現在,您可以看到,當您考慮將更多變體添加到列表中時,上述 (4 X 7 = 28) 的暴力組合 擴展 很容易 超出界限 。 在此類測試案例場景中, PICT 可以透過產生一組緊湊的參數結果來增加大量價值,以獲得對輸入參數的全面組合覆蓋。
TAEF 中的 PICT 支援
TAEF 提供 PICT 型測試的內建支援。
若要利用此功能,請像往常一樣撰寫 pict.exe 的輸入模型檔案。 請參閱上述範例資料夾中的 *.txt 檔案。 嘗試 PICT 是否如預期在模型檔案上執行,方法是先在命令提示字元上嘗試,如下所示:
pict.exe <model file> [/e:<seed file>]
Pict.exe 可與 TAEF 最新發行共用上的其餘二進位檔搭配使用。
一旦您完成撰寫 PICT 的模型檔案 (和種子檔案) ,並已針對命令提示字元的 pict.exe 進行驗證,您現在可以標記測試,讓 TAEF 知道它們是 PICT 驅動的測試。 如果您熟悉 TAEF 中可用的資料表型數據驅動測試,您會發現這非常相似。
原生程式碼:
1 class PictExample
2 {
3 TEST_CLASS(PictExample)
4
5 BEGIN_TEST_METHOD(SimpleTest)
6 TEST_METHOD_PROPERTY(L"DataSource", L"pict:PictExample.txt")
7 END_TEST_METHOD()
8
9 BEGIN_TEST_METHOD(TestWithSeed)
10 TEST_METHOD_PROPERTY(L"DataSource", L"pict:TestWithSeed.txt")
11 TEST_METHOD_PROPERTY(L"Pict:SeedingFile", L"TestWithSeed.sed")
12 TEST_METHOD_PROPERTY(L"Pict:Timeout", L"00:01:30")
13 END_TEST_METHOD()
14
15 BEGIN_TEST_METHOD(TestWithFunction)
16 TEST_METHOD_PROPERTY(L"DataSource", L"pict:TestWithFunction.txt")
17 END_TEST_METHOD()
18 };
託管代碼:
1 [TestClass]
2 public class CSharpPictExample
3 {
4 [TestMethod]
5 [DataSource("pict:ConstraintsTest.txt")]
6 [TestProperty("Pict:SeedingFile", "ConstraintsTest.seed")]
7 public void ConstraintsTest()
8 {
9 ...
10 }
11
12 [TestMethod]
13 [DataSource("pict:SumofSquareRoots.txt")]
14 public void SumOfSquareRoots()
15 {
16 ...
17 }
18
19 public TestContext TestContext
20 {
21 get { return m_testContext; }
22 set { m_testContext = value; }
23 }
24
25 private TestContext m_testContext;
26 }
如上述範例所示,您需要將模型檔案的名稱指定為DataSource。 您必須在模型檔案的名稱前面加上 “pict:” ,並將其提供為測試方法的 DataSource。 在受控測試的情況下,就像任何其他具有 TAEF 的數據驅動測試一樣,您必須提供 TestContext 屬性取得和設定方法,並在類別中具有相同的私人實例。
如果您想要將命令選項傳遞至 PICT,您可以使用中繼資料來達到此目的。 使用以下表格將 Pict.exe 的命令選項映射至 TAEF 中繼資料。
| pict.exe 指令語法 | 原生 TAEF 中繼資料語法 | 受控的 TAEF 中繼資料語法 |
|---|---|---|
| /o:3 | TEST_METHOD_PROPERTY(L“圖片:訂單”, L“3”) | [TestProperty(“Pict:Order”, “3”)] |
| /d:, | TEST_METHOD_PROPERTY(L“Pict:ValueSeparator”, L“,”) | [TestProperty(“Pict:值分隔符”, “,”)] |
| /a: | TEST_METHOD_PROPERTY(L“圖片:別名分隔符”, L” | |
| /n:~ | TEST_METHOD_PROPERTY(L“Pict:NegativeValuePrefix”, L“~”) | [TestProperty(“Pict:NegativeValuePrefix”, “~”)] |
| /e:測試種子 | TEST_METHOD_PROPERTY(L“Pict:SeedingFile”, L“test.seed”) | [TestProperty(“Pict:SeedingFile”, “test.seed”)] |
| /r | TEST_METHOD_PROPERTY(L“圖片:隨機”, L“true”) | [TestProperty(“Pict:隨機”, “true”)] |
| /r:33 | TEST_METHOD_PROPERTY(L“Pict:RandomSeed”, L“33”) | [TestProperty(“Pict:RandomSeed”, “33”)] |
| /c | TEST_METHOD_PROPERTY(L“Pict:CaseSensitive”, L“true”) | [TestProperty(“Pict:CaseSensitive”, “true”)] |
上述任何中繼資料都可以在命令提示字元、DataSource 屬性中設定,或設定為測試、類別或模組層級中繼資料,並依該順序設定優先順序。 若要在命令提示字元中設定它,請使用語法:
te.exe <test dll> /Pict:Order=3 /Pict:SeedingFile=test.seed
若要在 DataSource 屬性中設定中繼資料,請在模型檔名後附加問號字元(?),然後附加一組以 & 分隔的中繼資料名稱 = 中繼資料值組。 使用此方法時,中繼資料名稱的「Pict:」前置詞為可選的。 以下是範例:
TEST_METHOD_PROPERTY(L"DataSource", L"Pict:model.txt?Order=3&CaseSensitive=true&Random=true")
在幕後,TAEF 會提供您的輸入模型檔案和命令選項給 PICT,並取得結果。 如果 PICT 產生任何錯誤或警告,您會看到這些錯誤或警告會由 TAEF 記錄為警告。 針對 PICT 所產生的每個結果輸出列,TAEF 會重新執行該測試。
設定「Pict:RandomSeed」值會將「Pict:Random」的預設值從 false 變更為 true。 如此一來,您可以明確將 “Pict:Random” 設定為 false,讓 TAEF 忽略 “Pict:RandomSeed”。
允許 PICT.exe 在指定的模型檔案和種子檔案輸入上執行的預設逾時為 5 分鐘。 如果您的模型檔案更為複雜,且 PICT.exe 需要超過 5 分鐘才能傳回結果,您可以指定 “Pict:Timeout” 中繼資料,來覆寫此逾時設定,如上面的 CPP 範例所示。 在此範例中,以標準的TAEF Time-out格式指定 1.5 分鐘的逾時。 與其他 PICT 中繼資料一樣,「Pict:Timeout」中繼資料會繼承,因此可以針對整個類別或模組指定。
您可以在指定叫用期間從測試方法及其相關聯的設定和清除方法存取資料值,其方式與使用 TAEF 進行資料表型數據驅動測試的方式相同 - 針對原生程式碼使用 TestData 類別,並針對 Managed 程式碼使用 TestContext,如下所示:
原生程式碼:
1 void PictExample::SimpleTest()
2 {
3 String valueA;
4 if (SUCCEEDED(TestData::TryGetValue(L"A", valueA)))
5 {
6 Log::Comment(L"A retrieved was " + valueA);
7 }
8
9 String valueB;
10 if (SUCCEEDED(TestData::TryGetValue(L"B", valueB)))
11 {
12 Log::Comment(L"B retrieved was " + valueB);
13 }
14
15 String valueC;
16 if (SUCCEEDED(TestData::TryGetValue(L"C", valueC)))
17 {
18 Log::Comment(L"C retrieved was " + valueC);
19 }
20
21 unsigned int index;
22 if (SUCCEEDED(TestData::TryGetValue(L"index", index)))
23 {
24 Log::Comment(String().Format(L"At index %d", index));
25 }
26 }
託管代碼:
1 [TestClass]
2 public class CSharpPictExample
3 {
4 [TestMethod]
5 [DataSource("pict:ConstraintsTest.txt")]
6 public void ConstraintsTest()
7 {
8 Log.Comment("A is " + m_testContext.DataRow["A"]);
9 Log.Comment("B is " + m_testContext.DataRow["B"]);
10 Log.Comment("C is " + m_testContext.DataRow["C"]);
11 Log.Comment("D is " + m_testContext.DataRow["D"]);
12
13 UInt32 index = (UInt32)m_testContext.DataRow["Index"];
14 Log.Comment("At index " + index.ToString());
15 }
16
17 [TestMethod]
18 [DataSource("pict:SumofSquareRoots.txt")]
19 public void SumOfSquareRoots()
20 {
21 Log.Comment("A is " + m_testContext.DataRow["A"]);
22 Log.Comment("B is " + m_testContext.DataRow["B"]);
23
24 UInt32 index = (UInt32)m_testContext.DataRow["Index"];
25 Log.Comment("At index " + index.ToString());
26 }
27
28 public TestContext TestContext
29 {
30 get { return m_testContext; }
31 set { m_testContext = value; }
32 }
33
34 private TestContext m_testContext;
35 }
就像 TAEF 中的任何數據驅動測試一樣,「索引」是保留的,不應該用作參數名稱。 索引隱含地是指測試方法呼叫的索引,如果您的測試需要,則可從測試方法存取。
同樣重要的是要注意,在基於 PICT 的測試中,所有參數的數據類型都假設為 WEX::Common::String (原生)、String(託管)或 VT_BSTR(腳本)。 轉換和解釋由用戶決定。
現在您已完成使用 TAEF 撰寫 PICT 型測試,您可以從命令提示字元叫用它,並套用 TAEF 提供給它的所有命令功能:例如 /list 以取得將使用 PICT 輸出作為資料產生的所有測試方法清單, /listproperties 以取得測試方法名稱的清單,以及與它們相關聯的中繼資料和資料值等等。 在開始之前要注意的關鍵是確保 pict.exe 在您的路徑上。
以下是一些範例:
te Examples\CPP.Pict.Example.dll /list /name:*SimpleTest*
Test Authoring and Execution Framework v2.9.3k for x86
f:\ Examples\CPP.Pict.Example.dll
WEX::TestExecution::Examples::PictExample
WEX::TestExecution::Examples::PictExample::SimpleTest#0
WEX::TestExecution::Examples::PictExample::SimpleTest#1
WEX::TestExecution::Examples::PictExample::SimpleTest#2
WEX::TestExecution::Examples::PictExample::SimpleTest#3
WEX::TestExecution::Examples::PictExample::SimpleTest#4
WEX::TestExecution::Examples::PictExample::SimpleTest#5
WEX::TestExecution::Examples::PictExample::SimpleTest#6
WEX::TestExecution::Examples::PictExample::SimpleTest#7
WEX::TestExecution::Examples::PictExample::SimpleTest#8
WEX::TestExecution::Examples::PictExample::SimpleTest#9
WEX::TestExecution::Examples::PictExample::SimpleTest#10
WEX::TestExecution::Examples::PictExample::SimpleTest#11
WEX::TestExecution::Examples::PictExample::SimpleTest#12
WEX::TestExecution::Examples::PictExample::SimpleTest#13
WEX::TestExecution::Examples::PictExample::SimpleTest#14
WEX::TestExecution::Examples::PictExample::SimpleTest#15
WEX::TestExecution::Examples::PictExample::SimpleTest#16
WEX::TestExecution::Examples::PictExample::SimpleTest#17
WEX::TestExecution::Examples::PictExample::SimpleTest#18
WEX::TestExecution::Examples::PictExample::SimpleTest#19
WEX::TestExecution::Examples::PictExample::SimpleTest#20
WEX::TestExecution::Examples::PictExample::SimpleTest#21
WEX::TestExecution::Examples::PictExample::SimpleTest#22
WEX::TestExecution::Examples::PictExample::SimpleTest#23
要閱讀有關選擇標準(/select 和 /name)的更多信息,請參閱選擇維基頁面。
te Examples\Csharp.Pict.Example.dll /listproperties /select:"@Name='*SumofSquare*'
and @Data:index>10
Test Authoring and Execution Framework v2.9.3k for x86
f:\ Examples\CSharp.Pict.Example.dll
WEX.Examples.CSharpPictExample
WEX.Examples.CSharpPictExample.SumOfSquareRoots#11
Property[DataSource] = pict:SumofSquareRoots.txt
Data[a] = 1
Data[b] = ~-1
WEX.Examples.CSharpPictExample.SumOfSquareRoots#12
Property[DataSource] = pict:SumofSquareRoots.txt
Data[a] = 2
Data[b] = ~-1
上述範例顯示如何使用索引進行選取。 您也可以選擇根據資料值進行選擇。
te Examples\Csharp.Pict.Example.dll /listproperties /select:"@Name='*SumofSquare*'
and (@Data:A='1' and @Data:B='1')"
Test Authoring and Execution Framework v2.9.3k for x86
f:\ Examples\CSharp.Pict.Example.dll
WEX.Examples.CSharpPictExample
WEX.Examples.CSharpPictExample.SumOfSquareRoots#8
Property[DataSource] = pict:SumofSquareRoots.txt
Data[a] = 1
Data[b] = 1
PICT 結果快取
某些模型檔案可能會變得非常複雜,並且可能需要更長的時間才能由 Pict.exe處理。 TAEF 會嘗試在指定的 Te.exe執行期間快取結果,以減輕結果的處理時間。 如果相同執行執行中的後續測試參考相同的模型和種子檔案組合,TAEF 會使用快取的結果。 依預設,在每次執行結束時,都會刪除快取的結果。
如果您想要在後續執行中繼續利用快取的結果,您可以在執行期間在命令提示字元中指定 “/persistPictResults” 選項。 每當您為命令指定 “/persistPictResults” 時,第一次執行實際上會 pict.exe 執行,而且可能需要很長時間,但在模型和種子檔案未修改的情況下,所有後續執行都會使用快取的結果。 注意:若要進行後續執行,您需要繼續指定「/persistPictResults」。 您未指定的任何後續執行都會在該執行結束時刪除快取的結果。
如果保存 PICT 結果,並使用快取資料是預設要執行的動作,您可以將它設定為 te_cmd 環境變數的一部分,如下所示,而且不需要在每次執行時指定它。 如需te_cmd的詳細資訊,請參閱執行測試。
set te_cmd = /persistPictResults
快取的結果檔案會儲存在 %temp% 目錄中名為 「TAEF-PICT」 的資料夾中,如果 Te.exe 可以存取它,或儲存在啟動 Te.exe 的目前執行目錄中。 唯一可能出現結果不一致狀態的情況是,如果您在執行期間按 Ctrl + C。 在這種情況下,TAEF 會嘗試刪除快取的結果,但如果無法這麼做,您會看到錯誤。 該錯誤將提示您刪除緩存的結果位置。 如果不這樣做,可能會導致後續測試中出現未定義或錯誤的行為。
透過 TAEF 中的內建 PICT 支援,您現在可以在測試自動化中充分利用 PICT 中的功能以及 TAEF 中的功能。
DataSource 作為資源
您可以將 PICT 模型和植入檔案新增為測試模組中的資源。
在本機程式碼中,這是透過指定資源名稱而不是 DataSource 中繼資料中的檔案名稱來完成的。 以下是範例:
BEGIN_TEST_METHOD(ResourceNameDataSource)
TEST_METHOD_PROPERTY(L"DataSource", L"Pict:MyModelResourceName?SeedingFile=MySeedingResourceName")
END_TEST_METHOD()
「MyModelResourceName」 和 「MySeedingResourceName」 是 .rc 檔案中定義的資源名稱。 資源類型必須是 DATAFILE,而非在 資料表資料來源 中需要 DATASOURCE_XML 的資源類型。
MyModelResourceName DATAFILE "model.txt"
MySeedingResourceName DATAFILE "seed.txt"
DataSource 中繼資料值會維持在模型為檔案時相同。 同樣地,在本機程式碼中,您可以讓資源名稱與檔案名稱相同。 TAEF 會先尋找具有 DataSource 名稱的實際檔案的存在。 如果找不到檔案,則會透過查看測試模組的資源來繼續。 由於變更儲存在資源中的 DataSource 需要重新編譯,因此您可以在開發時將 DataSource 檔案複製到與測試 dll 相同的位置,並命名資源名稱以與檔名相同,以利用此設計。 完成測試後,將檔案移回(而不是複製)程式碼目錄並重新編譯以嵌入資源。