MSTest 屬性
MSTest 使用自訂屬性來識別和自訂測試。
為了提供更清楚的測試架構概觀,本節將 Microsoft.VisualStudio.TestTools.UnitTesting 命名空間的成員整理成相關功能的群組。
注意
名稱以 "Attribute" 結尾的屬性,無論結尾有沒有 "Attribute" 都可以使用。 具有無參數建構函式的屬性,在撰寫時可以包含括號或不含括號。 下列程式碼範例的運作方式相同:
[TestClass()]
[TestClassAttribute()]
[TestClass]
[TestClassAttribute]
用來識別測試類別和方法的屬性
每個測試類別必須具有 TestClass
屬性,且每個測試方法必須具有 TestMethod
屬性。
TestClassAttribute
TestClass 屬性會標示包含測試和 (選擇性) 初始化或清除方法的類別。
這個屬性可加以擴充以變更或擴充預設行為。
範例:
[TestClass]
public class MyTestClass
{
}
TestMethodAttribute
TestMethod 屬性是在 TestClass
內用來定義要執行的實際測試方法。
方法應該是定義為 public
、void
或 Task
的執行個體 ValueTask
方法 (從 MSTest v3.3 開始)。 它也可以是 async
,但不能是 async void
。
除非方法標示為 DataRow 屬性、DynamicData 屬性,或是提供測試案例數據給測試方法的類似屬性,否則方法應該會有零個參數。
請考慮下列範例測試類別:
[TestClass]
public class MyTestClass
{
[TestMethod]
public void TestMethod()
{
}
}
用於資料驅動測試的屬性
使用下列元素來設定資料導向測試。 如需詳細資訊,請參閱建立資料驅動型單元測試和使用組態檔定義資料來源。
DataRowAttribute
DataRow 屬性可讓您使用多個不同輸入來執行相同的測試方法。 其可在測試方法上出現一次或多次。 它應該與 TestMethod 屬性結合。
引數的數目和類型必須完全符合測試方法簽章。 請考慮下列有效的測試類別範例,示範 DataRowAttribute 使用與測試方法參數相符的內嵌自變數:
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, "message", true, 2.0)]
public void TestMethod1(int i, string s, bool b, float f)
{
// Omitted for brevity.
}
[TestMethod]
[DataRow(new string[] { "line1", "line2" })]
public void TestMethod2(string[] lines)
{
// Omitted for brevity.
}
[TestMethod]
[DataRow(null)]
public void TestMethod3(object o)
{
// Omitted for brevity.
}
[TestMethod]
[DataRow(new string[] { "line1", "line2" }, new string[] { "line1.", "line2." })]
public void TestMethod4(string[] input, string[] expectedOutput)
{
// Omitted for brevity.
}
}
注意
您也可以使用 params
功能來擷取 DataRowAttribute 的多個輸入。
[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" } })]
從 v3 開始:[DataRow(new string[] { "a" }, new string[] { "b" })]
設定 DataRowAttribute 屬性,即可修改 Visual Studio 中使用的顯示名稱,並針對 DisplayName 的每個執行個體修改記錄器。
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, 2, DisplayName = "Functional Case FC100.1")]
public void TestMethod(int i, int j) {}
}
您也可以藉由繼承 DataRowAttribute來建立自己的特製化 DataRow
屬性。
[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
或 static ValueTask
(從 MSTest v3.3 開始),在標示為 TestClassAttribute的類別中,並且只顯示一次。 初始化部分需要一個類型為 TestContext 的參數,而清理部分則可以不需要任何參數,或者從 MSTest 3.8 開始,可以具有一個類型為 TestContext的參數。
[TestClass]
public class MyTestClass
{
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext testContext)
{
}
[AssemblyCleanup]
public static void AssemblyCleanup() // Starting with MSTest 3.8, it can be AssemblyCleanup(TestContext testContext)
{
}
}
類別層級
ClassInitialize 屬性會在載入類別之前立即呼叫(但在靜態建構函式之後),並在卸除類別之後立即呼叫 ClassCleanup。
重要
根據預設,ClassCleanupAttribute 會在元件的最後一次測試之後觸發(類似於 AssemblyCleanupAttribute)。 您可以藉由在 屬性上設定 CleanupBehavior 來變更此行為。 或者,您可以使用元件屬性 ClassCleanupExecutionAttribute全域設定元件的行為。
您也可以控制繼承行為:僅適用於使用 InheritanceBehavior.None的目前類別,或使用 InheritanceBehavior.BeforeEachDerivedClass的所有衍生類別。
標示這些屬性的方法應在 static void
中定義為 static Task
、static ValueTask
或 TestClass
(從 MSTest v3.3 開始),並且只出現一次。 初始化部分需要類型為 TestContext 的一個參數,而清理部分可以不需要參數,或者從 MSTest 3.8 開始,可以有類型為 TestContext的一個參數。
[TestClass]
public class MyTestClass
{
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
}
[ClassCleanup]
public static void ClassCleanup() // Starting with MSTest 3.8, it can be ClassCleanup(TestContext testContext)
{
}
}
測試層級
TestInitialize 屬性會在測試啟動前立即呼叫,TestCleanup 則會在測試完成後立即呼叫。
TestInitializeAttribute 類似於類別建構函式,但通常更適合用於長時間或非同步初始化。 TestInitializeAttribute 一律會在建構函式之後呼叫,並針對每個測試呼叫(包括 數據驅動測試的每個項目)。
TestCleanupAttribute 類似於類別 Dispose
(或 DisposeAsync
),但通常更適合用於長時間或非同步清除。
TestCleanupAttribute 通常會在 DisposeAsync
/Dispose
之前呼叫,並在每個測試中呼叫(包括 數據驅動測試的每個項目)。
標示這些屬性的方法應在 void
中定義為 Task
、ValueTask
或 TestClass
(從 MSTest v3.3 開始),不使用參數,且出現一或多次。
[TestClass]
public class MyTestClass
{
[TestInitialize]
public void TestInitialize()
{
}
[TestCleanup]
public void TestCleanup()
{
}
}
用來控制測試執行的屬性
下列屬性可用來修改測試的執行方式。
TimeoutAttribute
Timeout 屬性可用來指定允許測試方法執行的時間上限 (毫秒)。 如果測試方法執行的時間超過指定時間,將會中止測試並標示為失敗。
這個屬性可以套用至任何測試方法或任何固件方法 (初始化和清除方法)。 您也可以使用 runsettings 檔案的逾時屬性,指定所有測試方法或所有測試固件方法的全域逾時值。
注意
不保證逾時值是精確值。 測試會在指定的時間過後中止,但在取消步驟之前可能需要更長的時間。
使用逾時功能時,會建立個別執行緒/工作來執行測試方法。 主要執行緒/工作負責監視逾時,並在達到逾時值時取消觀察方法執行緒/工作。
從 MSTest 3.6 開始,可以在屬性中指定 CooperativeCancellation 屬性 (或透過 runsettings 指定全域值),以啟用合作取消。 在此模式中,方法負責檢查取消權杖,並在測試發出訊號時中止測試,如同您在一般 async
方法中所做的一樣。 此模式效能較佳,並可讓您更精準地控制取消程序。 此模式可以同時套用至非同步和同步方法。
STATestClassAttribute
套用至測試類別時,STATestClass 屬性表示類別中的所有測試方法(以及類別中 [ClassInitialize]
和 [ClassCleanup]
方法)都應該在單個線程 Apartment (STA) 中執行。 當測試方法與需要 STA 的 COM 物件互動時,這個屬性很有用。
注意
僅 Windows 以及 3.6 和更高版本支援此功能。
STATestMethodAttribute
當套用至測試方法時,STATestMethod 屬性表示測試方法應在單一執行緒 (STA) 中執行。 當測試方法與需要 STA 的 COM 物件互動時,這個屬性很有用。
注意
僅 Windows 以及 3.6 和更高版本支援此功能。
ParallelizeAttribute
根據預設,MSTest 會循序執行測試。 元件層級屬性 Parallelize 屬性可用來平行執行測試。 您可以指定平行處理原則是否應在類別層級 (多個類別可以平行執行,但指定類別的測試會循序執行),或是在方法層級。
您也可以指定用於平行執行的執行緒數目上限。
0
的值 (預設值) 表示執行緒數目等於電腦上的邏輯處理器數目。
您也可以透過 runsettings 檔案的平行處理屬性來指定平行處理原則。
DoNotParallelizeAttribute
DoNotParallelize 屬性可用來防止在指定的組件中平行執行測試。 這個屬性可以在組件層級、類別層級或方法層級套用。
注意
根據預設,MSTest 會依序執行測試,因此,如果您已套用元件層級 Parallelize 屬性,則只需要使用這個屬性。
RetryAttribute
MSTest 3.8 中引進了 Retry
屬性。 此屬性會導致測試方法在失敗或逾時時重試。 它可讓您指定最大重試次數、重試之間的時間延遲,以及延遲退避類型,亦即固定或指數。
測試方法上預期只有一個 RetryAttribute
,而且 RetryAttribute
不能用於未標示 TestMethod的方法。
注意
RetryAttribute
衍生自抽象 RetryBaseAttribute
。 如果內建的 RetryAttribute
不適合您的需求,您也可以設計自己的重試機制。
公用程式屬性
DeploymentItemAttribute
DeploymentItem 屬性用於將指定為部署專案的檔案或資料夾複製到部署目錄(若未新增自定義輸出路徑,複製的檔案將會位於專案資料夾內的 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");
}
}
警告
不建議使用此屬性將檔案複製到部署目錄。
ExpectedExceptionAttribute
ExpectedException 屬性會定義測試方法預期擲回的例外狀況。 如果拋出預期的例外狀況,且例外狀況訊息符合預期的訊息,則測試會通過。
警告
這個屬性具有回溯相容性,因此不建議在新測試中使用。 請改用 Assert.ThrowsException
(或使用 MSTest 3.8 和更新版本時 Assert.ThrowsExactly
) 方法。
中繼資料屬性
下列屬性和指派給它們的值會顯示在特定測試方法的 Visual Studio
[屬性] 視窗中。 這些屬性不應透過測試的程式碼存取。 相反地,無論是由您透過 Visual Studio 的 IDE,或是由 Visual Studio 測試引擎,它們都會影響測試使用或執行的方式。 例如,其中一些屬性會顯示為 [測試管理員] 視窗和 [測試結果] 視窗中的資料行,這表示您可以使用它們來群組或排序測試和測試結果。 這類屬性其中之一為 TestPropertyAttribute,您可以利用它將任意中繼資料加入至測試。
例如,您可以使用它來儲存此測試所涵蓋之測試進行的名稱,方法是以 [TestProperty("Feature", "Accessibility")]
標示測試。 或者,您可以使用它,以 [TestProperty("ProductMilestone", "42")]
來儲存指出測試為哪種類型的指標。 您使用此屬性建立的屬性,以及您指派的屬性值,都會顯示在 Visual Studio [屬性] 視窗的 [測試專屬] 標題下。
- DescriptionAttribute
- IgnoreAttribute
- OwnerAttribute
- PriorityAttribute
- TestCategoryAttribute
- TestPropertyAttribute
- WorkItemAttribute
下列屬性將它們所裝飾的測試方法與 Team Foundation Server
團隊專案的專案階層架構中的實體產生關聯: