共用方式為


數據表數據源

請先確定您已熟悉 TAEF 的基本執行,並知道如何利用 編寫測試,再繼續進行本節。

既然您已撰寫及使用TAEF的基本測試自動化,您可以專注於相同測試程式碼可用來處理不同數據集的案例。 基於此目的,TAEF 提供數據驅動測試的「數據表型」方法。 讓我們看看一個簡單的範例,以瞭解如何撰寫數據驅動測試。

請考慮一個簡單的非數據驅動範例,其中您將大小和主題列印到主控台。 在此練習中,您將將此測試轉換成數據驅動測試。

1  namespace WEX { namespace TestExecution { namespace Examples
2  {
3     void DataDrivenTests::FirstTable()
4     {
5         int size = 12;
6         Log::Comment(String().Format(L"Size retrieved was %d", size));
7     }
8
9     void DataDrivenTests::SecondTable()
10    {
11        String theme = "Aero";
12        Log::Comment(L"Theme supplied as " + theme);
13    }
14 } /* namespace Examples */ } /* namespace TestExecution */ } /* namespace WEX */

定義數據

現在,您希望這個函數能適用於一組不同大小和主題。 換句話說,您希望函式可以取用的 Variant 數據值。 若要這樣做,請在 XML 檔案中定義兩個資料表,DataDrivenTests.xml :

1  <?xml version="1.0"?>
2  <Data>
3  <Table Id ="Table1">
4          <ParameterTypes>
5                  <ParameterType Name="Size">Int32</ParameterType>
6                  <ParameterType Name="Color">String</ParameterType>
7                  <ParameterType Name="Transparency">Boolean</ParameterType>
8          </ParameterTypes>
9          <Row Priority="1" Owner="C2">
10                 <Parameter Name="Size">12</Parameter>
11                 <Parameter Name="Color">Blue</Parameter>
12                 <Parameter Name="Transparency">True</Parameter>
13         </Row>
14         <Row Priority="2" Owner="wex">
15                 <Parameter Name="Size">4</Parameter>
16                 <Parameter Name="Color">White</Parameter>
17                 <Parameter Name="Transparency">False</Parameter>
18         </Row>
19         <Row Owner="C2">
20                 <Parameter Name="Size">9</Parameter>
21                 <Parameter Name="Color">Black</Parameter>
22                 <Parameter Name="Transparency">True</Parameter>
23         </Row>
24 </Table>
25 <Table id ="Table2">
26         <Row Description="ButtonTest" Owner="C2" Priority="1">
27                 <Parameter Name="Control">Button</Parameter>
28                 <Parameter Name="Theme">Aero</Parameter>
29         </Row>
30         <Row Description="ComboBoxTest" Priority="2">
31                 <Parameter Name="Control">ComboBox</Parameter>
32                 <Parameter Name="Theme">Classic</Parameter>
33         </Row>
34         <Row Description="ListviewTest" Owner="wex">
35                 <Parameter Name="Control">Listview</Parameter>
36                 <Parameter Name="Theme">AeroBasic</Parameter>
37         </Row>
38 </Table>
39 </Data>

您現在已定義兩個數據表 「Table1」 和 「Table2」。 您可以在相同的 XML 檔案中定義數個測試方法的數據表。

請注意,在 Table1 中,您已在前面定義 ParameterTypes,並選擇 “Size” 做為整數。 ParameterTypes 區段是選擇性的。 根據預設,如果未提供參數類型資訊,則會儲存為字串。 這是 「Table2」 中所有參數的情況。

數據表中定義的每個「數據列」都是您想要測試函式接受的一組數據(參數)值。 第 9、14 和 19 行會定義 FirstTable 函式將接受的 3 組數據。 同樣地,第 26、30 和 34 行會定義 SecondTable 的數據集。

請注意上述範例中的第 9、14、19、26、30 和 34 行 - 您可以定義 Row 特有的元數據。 現在有一種方式可讓元數據資訊與相同函式的數據集一起變更。 第一組數據 (第 9 行) 的優先順序為 1,第二組數據的優先順序為 2,第三組數據 (第 19 行) 預設為函式的優先順序。 所有數據列都會繼承數據表所關聯之函式的元數據。 如果在數據列層級再次指定相同的元數據,則會覆寫在函式層級定義的元數據值。

注意:XML 檔案架構定義與原生程式代碼和 Managed 程式代碼相同,但支援的類型定義除外。 如需如何定義數據的另一個範例,請參閱下方「受管理資料驅動測試」一節的開頭部分。 繼續進行原生數據驅動測試,以了解機器碼中允許的類型。

原生數據驅動測試

定義數據集並可供取用時,您現在需要一種方式,將測試函式限定為數據驅動測試,並將它與定義數據集的數據表產生關聯。 這是透過撰寫測試時的額外元數據來完成:

1  namespace WEX { namespace TestExecution { namespace Examples
2  {
3      class DataDrivenTests
4      {
5          TEST_CLASS(DataDrivenTests);
6
7          BEGIN_TEST_METHOD(SecondTable)
8              TEST_METHOD_PROPERTY(L"DataSource", L"Table:DataDrivenTests.xml#Table2")
9              TEST_METHOD_PROPERTY(L"Priority", L"3")
10         END_TEST_METHOD()
11
12         BEGIN_TEST_METHOD(FirstTable)
13             TEST_METHOD_PROPERTY(L"Priority", L"4")
14             TEST_METHOD_PROPERTY(L"DataSource", L"Table:DataDrivenTests.xml#Table1")
15         END_TEST_METHOD()
16     };
17 } /* namespace Examples */ } /* namespace TestExecution */ } /* namespace WEX */

若要將 XML 數據表與測試產生關聯,請將 『DataSource』 元數據新增至測試的 方法。 透過此關聯,TAEF 會使用指定的 DataSource 來驅動測試。 DataSource 值有三個部分:

  1. 'Table:' - 這會將數據源識別為 XML 數據表。
  2. 'DataDrivenTests.xml' - 這是包含 XML 資料表的檔案。
  3. '#Table2' - 在 '#' delimeter 之後,'Table2' 值會識別要使用的 XML 檔中的特定數據表。 單一 XML 數據表數據來源可以包含多個數據表。 TAEF 會查看 Table 元素的 XML 檔案,其中包含符合指定值的 『Id』 屬性。

您可能已在上述範例中觀察到 「SecondTable」 是在 「FirstTable」 之前定義的。 這表示 「SecondTable」 函式會在 「FirstTable」 函式之前執行,但您已定義 「Table1」,該數據表會對應至 「FirstTable」,在 「Table2」 之前,對應至 “SecondTable” 的數據表。 這是強調,在探索和執行數據驅動測試期間,數據表定義的順序無關緊要。

隨著數據源與測試方法的對應完成,您現在可以修改範例以從來源取得數據。 執行此動作之前,請先看看已發佈的頭檔 TestData.h。 感興趣的部分為:

1    class TestData
2    {
3    public:
4        template <typename T>
5        static HRESULT __stdcall TryGetValue(_In_z_ const wchar_t* pszString, T& result)
6        {
7            return Private::TestData<T>::TryGetValue(pszString, result);
8        }
9    };

第 5 行會顯示要呼叫的 API,以便擷取函式中的數據。 請查看可用於擷取的參數類型

好的 - 我們準備好重新撰寫範例了:

1  namespace WEX { namespace TestExecution { namespace Examples
2  {
3      void DataDrivenTests::FirstTable()
4      {
5          Log::Comment(L"I am in first table");
6          int size;
7          if (SUCCEEDED(TestData::TryGetValue(L"size", size)))
8          {
9              VERIFY_ARE_NOT_EQUAL(size, 0);
10             Log::Comment(String().Format(L"Size retrieved was %d", size));
11         }
12     }
13
14     void DataDrivenTests::SecondTable()
15     {
16         Log::Comment(L"I am in second table.");
17         String theme;
18         if (SUCCEEDED(TestData::TryGetValue(L"theme", theme)))
19         {
20             Log::Comment(L"Theme supplied as " + theme);
21         }
22     }
23 } /* namespace Examples */ } /* namespace TestExecution */ } /* namespace WEX */

第 7 行和第 18 行是主要變更部分,以便推動測試數據的運行。 沒有太大的變化。 看看執行數據驅動測試,瞭解如何在執行數據驅動測試時充分利用TAEF。

受控數據驅動測試

請考慮在終端機上列印矩形座標的範例。 首先,將這些座標定義為 XML 檔案中的資料集。

1  <?xml version="1.0"?>
2  <Data>
3  <Table Id="FirstTable">
4          <ParameterTypes>
5                  <ParameterType Name="Left">Int32</ParameterType>
6                  <ParameterType Name="Right">String</ParameterType>
7                  <ParameterType Name="Top">Integer</ParameterType>
8                  <ParameterType Name="Bottom">Int32</ParameterType>
9          </ParameterTypes>
10         <Row Priority="1" Owner="C2" Description="Zero rect">
11                 <Parameter Name="Left">0</Parameter>
12                 <Parameter Name="Right">0</Parameter>
13                 <Parameter Name="Top">0</Parameter>
14                 <Parameter Name="Bottom">0</Parameter>
15         </Row>
16         <Row Priority="2" Owner="wex" Description="normal rect">
17                 <Parameter Name="Left">12</Parameter>
18                 <Parameter Name="Right">25</Parameter>
19                 <Parameter Name="Top">10</Parameter>
20                 <Parameter Name="Bottom">50</Parameter>
21         </Row>
22         <Row Owner="C2" Description="invalid rect">
23                 <Parameter Name="Left">30</Parameter>
24                 <Parameter Name="Right">15</Parameter>
25                 <Parameter Name="Top">40</Parameter>
26                 <Parameter Name="Bottom">10</Parameter>
27         </Row>
28 </Table>
29 </Data>

在此案例中,定義數據表範圍中的數據集“FirstTable”,其定義於上述第 3 行。 您可以在相同的 XML 檔案中定義數個測試方法的數據表。

觀察 FirstTable 會預先定義 ParameterTypes,並呼叫 “Left” 做為 “Int32”。 ParameterTypes 區段是選擇性的。 根據預設,如果未提供參數類型資訊,則會儲存為 String。

查看支援 的參數類型清單

如果指定任何其他數據類型,測試將會擲回警告,並將它視為 String。

注意:類型字串不區分大小寫,但拼字應該完全如上所示。

數據表中定義的每個「數據列」都是一組您想要測試函式接受的數據(參數)值。 第 10、16 和 22 行定義了函式用來處理的 3 組數據。

請注意上述範例中的第 10、16 和 22 行 - 您可以定義 Row 特有的元數據。 您現在有辦法讓元數據資訊隨著相同函式的數據集而變更。 第一組數據 (第 10 行) 的優先順序為 1,第二組數據的優先順序為 2,第三組數據 (第 22 行) 預設為函式的優先順序。 所有數據列都會繼承數據表所關聯之函式的元數據。 如果在數據列層級再次指定相同的元數據,則會覆寫在函式層級定義的元數據值。

注意:XML 檔案架構定義與原生程式代碼和 Managed 程式代碼相同,但支援的類型定義除外。 如需如何定義此專案的另一個範例,請參閱此頁面頂端的[定義數據] 區段。

現在,您已定義所有資料。 下列範例示範如何存取它。

1  namespace WEX.Examples
2  {
3      using Microsoft.VisualStudio.TestTools.UnitTesting;
4      using System;
5      using System.Collections;
6      using WEX.Logging.Interop;
7      using WEX.TestExecution;
8
9      [TestClass]
10     public class CSharpDataDrivenTests
11     {
12         [TestMethod]
15         [DataSource("Table:CSharpDataDrivenTests.xml#FirstTable")]
16         public void First()
17         {
18             Console.WriteLine("Left is " + m_testContext.DataRow["Left"].ToString());
19
20             Log.Comment("In CSharpDataDrivenTests.First");
21         }
22
23         [TestMethod]
24         public void Second()
25         {
26             Log.Comment("In CSharpDataDrivenTests.Second");
27             Verify.IsTrue(true);
28         }
29
30         public TestContext TestContext
31         {
32             get { return m_testContext; }
33             set { m_testContext = value; }
34         }
35
36         private TestContext m_testContext;
37     }
38 }

將 XML 表格與受控程式碼中的指定測試方法產生關聯的方式與原生程式碼非常相似,只需套用 "DataSource" 元數據即可。 和之前一樣,它是由三個部分所組成:

  1. 'Table:' - 將數據源識別為 XML 數據表。
  2. 'CSharpDataDrivenTests.xml' - 包含 XML 資料表的檔案。
  3. '#FirstTable' - 在 '#' delimeter 之後,'FirstTable' 值會識別要使用的 XML 檔案中的特定數據表。 TAEF 會查看 Table 元素的 XML 檔案,其中包含符合指定值的 『Id』 屬性。

請注意,第二個函式不是數據驅動。 您可以選擇只讓部分測試成為資料驅動。 您也可以選擇讓每個測試都在不同的 XML 檔案中定義其資料表。

在第 36 行中,您會定義私人 TestContext 屬性,例如 VSTS 建議 TestContext 類別。 您也會定義此屬性的公用評估員(第 30 到 34 行)。 在內部,TAEF 會載入 TestContext 的字典屬性,並將對應的數據集放在焦點中。

TestContext 定義於 Microsoft.VisualStudio.TestTools.UnitTesting 中。 請參閱上述範例中的第 3 行。 您應該已在管理的測試編寫中包含此作為參考。 因此,撰寫數據驅動測試不需要其他參考。

在上述範例的第 18 行中,您會示範如何在 函式中擷取數據。 請注意,數據位於 m_testContext.DataRow 中。

使用名稱而非索引來識別資料列

TAEF 可讓您擁有更有意義的 『Name』 屬性,而不是 Index 來識別 DataSource 中的任何 DataRow。 若要這樣做,只要在 DataSource 中的數據列層級新增 『Name』 元數據即可。 此頁面上的第一個範例可以修改為使用此功能,如下所示:

1  <?xml version="1.0"?>
2  <Data>
3  <Table id ="Table1">
4          <ParameterTypes>
5                  <ParameterType Name="Size">Int32</ParameterType>
6                  <ParameterType Name="Color">String</ParameterType>
7                  <ParameterType Name="Transparency">Boolean</ParameterType>
8          </ParameterTypes>
9          <Row Name='BlueTransparent' Priority="1" Owner="C2">
10                 <Parameter Name="Size">12</Parameter>
11                 <Parameter Name="Color">Blue</Parameter>
12                 <Parameter Name="Transparency">True</Parameter>
13         </Row>
14         <Row Priority="2" Owner="wex">
15                 <Parameter Name="Size">4</Parameter>
16                 <Parameter Name="Color">White</Parameter>
17                 <Parameter Name="Transparency">False</Parameter>
18         </Row>
19         <Row Name='BlackTransparent' Owner="C2">
20                 <Parameter Name="Size">9</Parameter>
21                 <Parameter Name="Color">Black</Parameter>
22                 <Parameter Name="Transparency">True</Parameter>
23         </Row>
24 </Table>
25 ...
39 </Data>

在上述修改的範例中,'BlueTransparent' 會對應至索引 0。 索引為 1 的列沒有給予特定名稱,而索引為 2 的列則有名稱 'BlackTransparent' 與其相關聯。 您仍然可以使用選取查詢來尋找 『Table1』 中的索引 0 或 2,它會找到正確的數據列。 但是,在執行或列出 DLL 時,結果並不是看到:

<qualified name of the test method>#<index>

您將會改為看到:

<qualified name of the test method>#<name property provided at Row level>

在數據列層級提供 「Name」 屬性的數據列。 如果未針對任何 Row 提供 「Name」 屬性,例如在上述索引 1 的情況下,它會預設在方法的限定名稱上具有 #<索引>

請注意,藉由在列層級提供「名稱」屬性,您實質上改變了TAEF解譯方法調用實例名稱的方式,以配合相應的數據列。

作為執行時參數的 DataSource

TAEF 支援提供數據源做為運行時間參數。 此語法如下所示:

te <test dll names> /p:<DataSource runtime name>=Table:<DataSoure XML file>#<Table Id>

在撰寫相關測試時,您必須將「p:<資料來源執行時間名稱>」指定為您的資料來源。 請記住,您必須在執行時間指定完整的字串 - XML 檔案名稱以及資料表識別碼 。 如果您的數據源是在運行時間提供,那麼 TableId 預期不會作為測試資料的元數據提供。 “Table:” 前置詞會指定您要尋找數據表數據源。

您可以使用版本分享上可用的其中一個範例來試用:

te Examples\CPP.RuntimeDataSource.Example.dll /p:MyDataSource=Table:RuntimeDataSourceExample.xml#SimpleTable

DataSource 作為資源

TAEF 可讓您將 DataSource 新增為測試模組的資源,只要符合以下條件:

如果是原生測試模組,您可以將 DataSource 指定為資源識別碼或資源名稱,以執行此動作。 以下是程式代碼範例:

BEGIN_TEST_METHOD(ResourceNameDataSource)
    TEST_METHOD_PROPERTY(L"DataSource", L"Table:MyResourceName#SimpleTable")
END_TEST_METHOD()

“MyResourceName” 是 ResourceDataSource.rc 檔案中定義的資源名稱,在此案例中為:

MyResourceName DATASOURCE_XML "ResourceDataSource.xml"

在受控測試模塊的情況下,資源只能以特定方式指定,如下列 來源 檔案代碼段所示:

LANGUAGE_NEUTRAL_MANAGED_RESOURCES = CSharpAdvancedDataDrivenTests.xml

當指定 DataSource XML 檔案時,DataSource 元數據規格會維持不變。 類似於 Managed 程式代碼中的案例,您可以將資源名稱設定為與 XML 檔名相同的名稱。 因此,請務必瞭解TAEF會先尋找具有DataSource名稱的實際檔案是否存在。 如果找不到這類 XML 檔案,則只會繼續尋找具有指定資源名稱或標識碼的測試模組中的測試資源。由於將 DataSource 指定為資源需要重新編譯,因此您可以將 DataSource XML 檔案複製到與測試 dll 相同的位置,同時開發時利用此設計(並將資源名稱命名為與 XML 檔名相同)。 完成測試之後,請將 XML 複製回程式代碼目錄,然後重新編譯為資源。 別忘了從執行目錄刪除 XML 檔案! :)

範例操作說明

若要掌握表格型數據驅動測試的各個層面,請參閱一些範例解析。