Share via


在單元測試中使用 MSTest 架構

MSTest 架構支援 Visual Studio 中的單元測試。 當您撰寫單元測試程式碼時,請使用 Microsoft.VisualStudio.TestTools.UnitTesting 命名空間中的類別和成員。 在調整從程式碼產生的單元測試時,也可以利用它們。

架構成員

為了提供更清楚的單元測試架構概觀,本節將 Microsoft.VisualStudio.TestTools.UnitTesting 命名空間的成員整理成相關功能的群組。

注意

屬性元素 (其名稱結尾是 "Attribute") 可搭配或不搭配結尾的 "Attribute" 使用,而且適用於具有或不含括弧的無參數建構函式。 例如,下列程式碼範例的運作完全相同:

[TestClass()]

[TestClassAttribute()]

[TestClass]

[TestClassAttribute]

用來識別測試類別和方法的屬性

每個測試類別必須具有 TestClass 屬性,且每個測試方法必須具有 TestMethod 屬性。 如需詳細資訊,請參閱 Anatomy of a unit test(單元測試的結構)。

TestClassAttribute

TestClass 屬性會標示包含測試和 (選擇性) 初始化或清除方法的類別。

這個屬性可加以擴充以更新或擴充行為。

範例:

[TestClass]
public class MyTestClass
{    
}

TestMethodAttribute

TestMethod 屬性是在 TestClass 內用來定義要執行的實際測試方法。

此方法應該是定義為 public voidpublic Task 的執行個體方法 (選擇性 async),而且是無參數的。

範例

[TestClass]
public class MyTestClass
{
    [TestMethod]
    public void TestMethod()
    {
    }
}
[TestClass]
public class MyTestClass
{
    [TestMethod]
    public async Task TestMethod()
    {
    }
}

用於資料驅動測試的屬性

使用下列項目設定資料驅動型單元測試。 如需詳細資訊,請參閱建立資料驅動型單元測試使用組態檔定義資料來源

DataRow

DataRowAttribute 可讓您提供叫用測試方法時所使用的內嵌資料。 其可在測試方法上出現一次或多次。 其應該與 TestMethodAttributeDataTestMethodAttribute 結合。

引數的數目和類型必須完全符合測試方法簽章。

有效呼叫的範例:

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, "message", true, 2.0)]
    public void TestMethod1(int i, string s, bool b, float f) {}
    
    [TestMethod]
    [DataRow(new string[] { "line1", "line2" })]
    public void TestMethod2(string[] lines) {}

    [TestMethod]
    [DataRow(null)]
    public void TestMethod3(object o) {}

    [TestMethod]
    [DataRow(new string[] { "line1", "line2" }, new string[] { "line1.", "line2." })]
    public void TestMethod4(string[] input, string[] expectedOutput) {}
}

請注意,您也可以使用 params 功能來擷取 DataRow 的多項輸入。

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, 2, 3, 4)]
    public void TestMethod(params int[] values) {}
}

無效組合的範例:

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, 2)] // Not valid, we are passing 2 inline data but signature expects 1
    public void TestMethod1(int i) {}

    [TestMethod]
    [DataRow(1)] // Not valid, we are passing 1 inline data but signature expects 2
    public void TestMethod2(int i, int j) {}

    [TestMethod]
    [DataRow(1)] // Not valid, count matches but types do not match
    public void TestMethod3(string s) {}
}

注意

從 MSTest v3 開始,當您想要傳遞正好 2 個陣列時,您就不再需要將第二個陣列包裝在物件陣列中。 之前:[DataRow(new string[] { "a" }, new object[] { new string[] { "b" } })] In v3 onward: [DataRow(new string[] { "a" }, new string[] { "b" })]

設定 DisplayName 屬性,即可修改 Visual Studio 中使用的顯示名稱,並針對 DataRowAttribute 的每個執行個體修改記錄器。

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, 2, DisplayName= "Functional Case FC100.1")]
    public void TestMethod(int i, int j) {}
}

您也可繼承 DataRowAttribute 以建立自己的特製化資料列屬性。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyCustomDataRowAttribute : DataRowAttribute
{
}

[TestClass]
public class TestClass
{
    [TestMethod]
    [MyCustomDataRow(1)]
    public void TestMethod(int i) {}
}

用於提供初始化和清除的屬性

以下列屬性裝飾的方法會在您指定的時間呼叫。 如需詳細資訊,請參閱 Anatomy of a unit test(單元測試的結構)。

組件

AssemblyInitialize 會在您的組件載入之後立即呼叫,而 AssemblyCleanup 會在您的組件卸載之前立即呼叫。

以這些屬性標示的方法應該定義為 static voidstatic Task (在 TestClass 中),而且只出現一次。 初始化組件需要一個 TestCoNtext 類型的引數,而清除不需要引數。

[TestClass]
public class MyTestClass
{
    [AssemblyInitialize]
    public static void AssemblyInitialize(TestContext testContext)
    {
    }

    [AssemblyCleanup]
    public static void AssemblyCleanup()
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [AssemblyInitialize]
    public static async Task AssemblyInitialize(TestContext testContext)
    {
    }

    [AssemblyCleanup]
    public static async Task AssemblyCleanup()
    {
    }
}

類別

ClassInitialize 會在您的類別載入之前立即呼叫 (但在靜態建構函式之後),而 ClassCleanup 會在您的類別卸載之後立即卸載呼叫。

可以控制繼承行為:僅適用於使用 InheritanceBehavior.None 的目前類別,或使用 InheritanceBehavior.BeforeEachDerivedClass 的所有衍生類別。

您也可以設定類別清除應該在類別結尾或在組件結尾執行 (從 MSTest v4 開始不再提供支援,因為 EndOfClass 是預設值,且只有類別清除行為)。

以這些屬性標示的方法應該定義為 static voidstatic Task (在 TestClass 中),而且只出現一次。 初始化組件需要一個 TestCoNtext 類型的引數,而清除不需要引數。

[TestClass]
public class MyTestClass
{
    [ClassInitialize]
    public static void ClassInitialize(TestContext testContext)
    {
    }

    [ClassCleanup]
    public static void ClassCleanup()
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [ClassInitialize]
    public static async Task ClassInitialize(TestContext testContext)
    {
    }

    [ClassCleanup]
    public static async Task ClassCleanup()
    {
    }
}

Test

TestInitialize 會在測試開始之前立即呼叫,而 TestCleanup 會在測試完成之後立即呼叫。

TestInitialize 類似於類別建構函式,但通常更適合用於長時間或非同步初始化。 TestInitialize 一律會在建構函式之後呼叫並針對每個測試呼叫 (包括資料驅動測試的每個資料列)。

TestCleanup 類似於類別 Dispose (或 DisposeAsync),但通常更適合用於長時間或非同步清除。 TestCleanup 一律會在 DisposeAsync/Dispose 的前面呼叫並針對每個測試呼叫 (包括資料驅動測試的每個資料列)。

以這些屬性標示的方法應定義為 voidTask (在 TestClass 中),應為無參數,而且會出現一或多次。

[TestClass]
public class MyTestClass
{
    [TestInitialize]
    public void TestInitialize()
    {
    }

    [TestCleanup]
    public void TestCleanup()
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [TestInitialize]
    public async Task TestInitialize()
    {
    }

    [TestCleanup]
    public async Task TestCleanup()
    {
    }
}

單元測試可以依照其使用各種判斷提示、例外狀況及屬性的方式,確認特定的應用程式行為。 如需詳細資訊,請參閱使用 Assert 類別

TestContext 類別

下列屬性和指派給它們的值會顯示在特定測試方法的 Visual Studio [屬性] 視窗中。 這些屬性並不應該透過單元測試的程式碼存取。 相反地,無論是由您透過 Visual Studio 的 IDE,或是由 Visual Studio 測試引擎,它們都會影響單元測試使用或執行的方式。 例如,其中一些屬性會顯示為 [測試管理員] 視窗和 [測試結果] 視窗中的資料行,這表示您可以使用它們來群組或排序測試和測試結果。 這類屬性其中之一為 TestPropertyAttribute,您可以利用它來將任意中繼資料加入至單元測試。 例如,您可以 [TestProperty("TestPass", "Accessibility")] 標示單元測試,使用該屬性來儲存此測試所涵蓋「測試成功」的名稱。 或者,您可以使用它,以 [TestProperty("TestKind", "Localization")] 來儲存指出測試為哪種類型的指標。 您使用此屬性建立的屬性,以及您指派的屬性值,都會顯示在 Visual Studio [屬性] 視窗的 [測試專屬] 標題下。

DeploymentItemAttribute

MSTest V2 架構引進了 DeploymentItemAttribute,用於將指定為部署項目的檔案或資料夾複製到部署目錄 (若未新增自訂輸出路徑,所複製的檔案將會位於專案資料夾內的 TestResults 資料夾中)。 部署目錄是所有部署項目與測試專案 DLL 一起存在的位置。

其可用於測試類別 (以 TestClass 屬性標記的類別) 或測試方法 (以 TestMethod 屬性標示的方法)。

使用者可以有此屬性的多個執行個體來指定以個以上的項目。

您可以在這裡查看其建構函式

範例

[TestClass] 
[DeploymentItem(@"C:\classLevelDepItem.xml")]   // Copy file using some absolute path
public class UnitTest1
{
    [TestMethod]
    [DeploymentItem(@"..\..\methodLevelDepItem1.xml")]   // Copy file using a relative path from the dll output location
    [DeploymentItem(@"C:\DataFiles\methodLevelDepItem2.xml", "SampleDataFiles")]   // File will be added under a SampleDataFiles in the deployment directory
    public void TestMethod1()
    {
        string textFromFile = File.ReadAllText("classLevelDepItem.xml");
    }
}

測試組態類別

用來產生報表的屬性

本節中的屬性將它們所裝飾的測試方法與 Team Foundation Server 團隊專案的專案階層架構中的實體產生關聯。

與私用存取子搭配使用的類別

您可以為私用方法產生單元測試。 這個層代會建立私用存取子類別,該類別會具現化 PrivateObject 類別的物件。 PrivateObject 類別是一種包裝函式類別,會使用反映做為私用存取子程序的一部分。 PrivateType 類別很類似,不過是用來呼叫私用靜態方法,而不是呼叫私用執行個體方法。

另請參閱