在單元測試中使用 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 void
或 public Task
的執行個體方法 (選擇性 async
),而且是無參數的。
範例
[TestClass]
public class MyTestClass
{
[TestMethod]
public void TestMethod()
{
}
}
[TestClass]
public class MyTestClass
{
[TestMethod]
public async Task TestMethod()
{
}
}
用於資料驅動測試的屬性
使用下列項目設定資料驅動型單元測試。 如需詳細資訊,請參閱建立資料驅動型單元測試和使用組態檔定義資料來源。
DataRow
DataRowAttribute
可讓您提供叫用測試方法時所使用的內嵌資料。 其可在測試方法上出現一次或多次。 其應該與 TestMethodAttribute
或 DataTestMethodAttribute
結合。
引數的數目和類型必須完全符合測試方法簽章。
有效呼叫的範例:
[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 void
或 static 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 void
或 static 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
的前面呼叫並針對每個測試呼叫 (包括資料驅動測試的每個資料列)。
以這些屬性標示的方法應定義為 void
或 Task
(在 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 和相關例外狀況
單元測試可以依照其使用各種判斷提示、例外狀況及屬性的方式,確認特定的應用程式行為。 如需詳細資訊,請參閱使用 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 類別很類似,不過是用來呼叫私用靜態方法,而不是呼叫私用執行個體方法。