共用方式為


MSTest 屬性

MSTest 使用自訂屬性來識別和自訂測試。

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

注意

名稱以 "Attribute" 結尾的屬性,無論結尾有沒有 "Attribute" 都可以使用。 具有無參數建構函式的屬性,在撰寫時可以包含括號或不含括號。 下列程式碼範例的運作方式相同:

[TestClass()]

[TestClassAttribute()]

[TestClass]

[TestClassAttribute]

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

每個測試類別必須具有 TestClass 屬性,且每個測試方法必須具有 TestMethod 屬性。

TestClassAttribute

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

這個屬性可加以擴充以變更或擴充預設行為。

範例:

[TestClass]
public class MyTestClass
{
}

TestMethodAttribute

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

方法應該是定義為 publicvoidTask 的執行個體 ValueTask 方法 (從 MSTest v3.3 開始)。 它也可以是 async,但不能是 async void

此方法應該有零個參數,除非搭配使用 [DataRow][DynamicData] 或類似的屬性,以提供測試案例資料給測試方法。

請考慮下列範例測試類別:

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

用於資料驅動測試的屬性

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

DataRowAttribute

DataRowAttribute 可讓您使用多個不同的輸入來執行相同的測試方法。 其可在測試方法上出現一次或多次。 它應該與 TestMethodAttribute結合。

引數的數目和類型必須完全符合測試方法簽章。 請考慮下列有效測試類別範例,其中示範如何使用 DataRow 屬性搭配內置引數以配合測試方法參數:

[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 功能來擷取 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" } })]從 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 以建立自己的特製化資料列屬性。

[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 Taskstatic ValueTaskTestClass (從 MSTest v3.3 開始),並且只出現一次。 初始化部分需要一個類型為 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)
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [AssemblyInitialize]
    public static async Task AssemblyInitialize(TestContext testContext)
    {
    }

    [AssemblyCleanup]
    public static async Task AssemblyCleanup() // Starting with MSTest 3.8, it can be AssemblyCleanup(TestContext testContext)
    {
    }
}

類別層級

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

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

您也可以設定是否應在類別結尾或在組件結尾執行類別清除。

標示這些屬性的方法應在 static void 中定義為 static Taskstatic ValueTaskTestClass (從 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)
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [ClassInitialize]
    public static async Task ClassInitialize(TestContext testContext)
    {
    }

    [ClassCleanup]
    public static async Task ClassCleanup() // Starting with MSTest 3.8, it can be ClassCleanup(TestContext testContext)
    {
    }
}

測試層級

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

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

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

標示這些屬性的方法應在 void 中定義為 TaskValueTaskTestClass (從 MSTest v3.3 開始),不使用參數,且出現一或多次。

[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()
    {
    }
}

用來控制測試執行的屬性

下列屬性可用來修改測試的執行方式。

TimeoutAttribute

Timeout 屬性可用來指定允許測試方法執行的時間上限 (毫秒)。 如果測試方法執行的時間超過指定時間,將會中止測試並標示為失敗。

這個屬性可以套用至任何測試方法或任何固件方法 (初始化和清除方法)。 您也可以使用 runsettings 檔案的逾時屬性,指定所有測試方法或所有測試固件方法的全域逾時值。

注意

不保證逾時值是精確值。 測試會在指定的時間過後中止,但可能需要數毫秒的時間。

使用逾時功能時,會建立個別執行緒/工作來執行測試方法。 主要執行緒/工作負責監視逾時,並在達到逾時值時取消觀察方法執行緒/工作。

從 MSTest 3.6 開始,可以在屬性中指定 CooperativeCancellation 屬性 (或透過 runsettings 指定全域值),以啟用合作取消。 在此模式中,方法負責檢查取消權杖,並在測試發出訊號時中止測試,如同您在一般 async 方法中所做的一樣。 此模式效能較佳,並可讓您更精準地控制取消程序。 此模式可以同時套用至非同步和同步方法。

STATestClassAttribute

套用至測試類別時,[STATestClass] 屬性會指出類別中的所有測試方法 (以及 [ClassInitialize][ClassCleanup] 方法) 都應該在單一執行緒 Apartment (STA) 中執行。 當測試方法與需要 STA 的 COM 物件互動時,這個屬性很有用。

注意

僅 Windows 以及 3.6 和更高版本支援此功能。

STATestMethodAttribute

套用至測試方法時,[STATestMethod] 屬性會指出測試方法應在單一執行緒 Apartment (STA) 中執行。 當測試方法與需要 STA 的 COM 物件互動時,這個屬性很有用。

注意

僅 Windows 以及 3.6 和更高版本支援此功能。

ParallelizeAttribute

根據預設,MSTest 會循序執行測試。 Parallelize 屬性可用來平行執行測試。 這是組件層級屬性。 您可以指定平行處理原則是否應在類別層級 (多個類別可以平行執行,但指定類別的測試會循序執行),或是在方法層級

您也可以指定用於平行執行的執行緒數目上限。 0 的值 (預設值) 表示執行緒數目等於電腦上的邏輯處理器數目。

您也可以透過 runsettings 檔案的平行處理屬性來指定平行處理原則。

DoNotParallelizeAttribute

DoNotParallelize 屬性可用來防止在指定的組件中平行執行測試。 這個屬性可以在組件層級、類別層級或方法層級套用。

注意

根據預設,MSTest 會循序執行測試,因此,只有當您已在組件層級套用 [Parallelize] 屬性時需要使用此屬性。

公用程式屬性

DeploymentItemAttribute

MSTest 架構引進了 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");
    }
}

警告

不建議使用此屬性將檔案複製到部署目錄。

ExpectedExceptionAttribute

MSTest 架構採用了 ExpectedExceptionAttribute,可以標示測試方法期待特定類型的例外狀況。 如果擲回預期的例外狀況,且該例外狀況訊息符合預期的訊息,則測試將會通過。

警告

這個屬性具有回溯相容性,因此不建議在新測試中使用。 請改用 Assert.ThrowsException (或使用 MSTest 3.8 和更新版本時 Assert.ThrowsExactly) 方法。

中繼資料屬性

下列屬性和指派給它們的值會顯示在特定測試方法的 Visual Studio [屬性] 視窗中。 這些屬性不應透過測試的程式碼存取。 相反地,無論是由您透過 Visual Studio 的 IDE,或是由 Visual Studio 測試引擎,它們都會影響測試使用或執行的方式。 例如,其中一些屬性會顯示為 [測試管理員] 視窗和 [測試結果] 視窗中的資料行,這表示您可以使用它們來群組或排序測試和測試結果。 這類屬性其中之一為 TestPropertyAttribute,您可以利用它將任意中繼資料加入至測試。

例如,您可以使用它來儲存此測試所涵蓋之測試進行的名稱,方法是以 [TestProperty("Feature", "Accessibility")] 標示測試。 或者,您可以使用它,以 [TestProperty("ProductMilestone", "42")] 來儲存指出測試為哪種類型的指標。 您使用此屬性建立的屬性,以及您指派的屬性值,都會顯示在 Visual Studio [屬性] 視窗的 [測試專屬] 標題下。

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