TestContext 類別

TestContext 類別提供實用的資訊和工具,以協助管理測試執行。 它可讓您存取測試回合的詳細數據,並調整測試環境。 這個類別是 Microsoft.VisualStudio.TestTools.UnitTesting 命名空間的一部分。

存取 TestContext 物件

TestContext 物件可在下列內容中使用:

  • AssemblyInitialize的參數是 ClassInitialize 方法。 在此內容中,無法使用與測試回合相關的屬性。
  • 從 3.6 開始,ClassCleanup 方法可以選擇性地作為 AssemblyCleanup的參數。 在此內容中,無法使用與測試回合相關的屬性。
  • 作為測試類別的屬性。 在這個情境中,可以取得與測試執行相關的屬性。
  • 作為測試類別的建構函式參數(從 v3.6 開始)。 建議使用這種方式而非屬性,因為它可以在建構函式中提供對物件的存取權。 屬性只有在建構函式執行之後才能使用。 如此一來,也有助於確保物件的不變性,並允許編譯程式強制物件不是 Null。
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class MyTestClassTestContext
{
    public TestContext TestContext { get; set; }

    [AssemblyInitialize]
    public static void AssemblyInitialize(TestContext context)
    {
        // Access TestContext properties and methods here. The properties related to the test run are not available.
    }

    [ClassInitialize]
    public static void ClassInitialize(TestContext context)
    {
        // Access TestContext properties and methods here. The properties related to the test run are not available.
    }

    [TestMethod]
    public void MyTestMethod()
    {
        // Access TestContext properties and methods here
    }
}

或者使用 MSTest 3.6+:

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class MyTestClassTestContextThroughCtor
{
    private readonly TestContext _testContext;

    public MyTestClassTestContextThroughCtor(TestContext testContext)
    {
        _testContext = testContext;
    }

    [AssemblyInitialize]
    public static void AssemblyInitialize(TestContext context)
    {
        // Access TestContext properties and methods here. The properties related to the test run are not available.
    }

    [ClassInitialize]
    public static void ClassInitialize(TestContext context)
    {
        // Access TestContext properties and methods here. The properties related to the test run are not available.
    }

    [TestMethod]
    public void MyTestMethod()
    {
        // Access TestContext properties and methods here
    }
}

TestContext 成員

TestContext 類別提供測試回合的相關屬性,以及操作測試環境的方法。 本節涵蓋最常用的屬性和方法。

測試運行資訊

TestContext 提供測試回合的相關信息,例如:

每測試暫存目錄

Important

TestContext.TestTempDirectory 計畫於 MSTest 4.4 版本中提供,且僅在預覽版本中提供,直到 MSTest 4.4.0 版本發布。

作為私人的練習空間。TestContext.TestTempDirectory MSTest 只有在你第一次存取該屬性時才會建立該目錄,且每次測試執行都會獲得一個獨特的目錄。 每個資料列也會接收自己的目錄,因此平行測試不會共享路徑。

string path = Path.Combine(TestContext.TestTempDirectory!, "output.json");
File.WriteAllText(path, json);

MSTest 在可能時建立該 TestResultsDirectory 目錄,當結果路徑不可用、過長或唯讀時,則回退到系統暫存目錄。 MSTest 在測試通過後刪除該目錄,並在未通過結果後保留該目錄。 將環境變數設定MSTEST_TEST_TEMP_DIRECTORY_RETAIN1true或保留所有結果的目錄。

當測試通過時,從 為 AddResultFile的目錄註冊檔案,MSTest 會保留該目錄,直到主機收集附件。 清理是盡力而為,不會改變測試結果。

TestTempDirectory可用於 .NET 和 .NET Framework 目標,但不適用於 UWP 或 WinUI 目標。 這個屬性不會改變程序目前的目錄。

在 MSTest 3.7 和更新版本中,TestContext 類別也提供有助於 TestInitializeTestCleanup 方法的新屬性:

數據驅動測試

在 MSTest 3.7 和更新版本中,屬性 TestContext.TestData 可用來存取 TestInitializeTestCleanup 方法期間目前測試的數據。

以 .NET Framework 為目標時,TestContext 可讓您使用 DataRowDataConnection 等屬性,擷取和設定資料驅動測試中每次迭代的資料(適用於 DataSource型測試)。

請考慮下列 CSV 檔案 TestData.csv

Number,Name
1,TestValue1
2,TestValue2
3,TestValue3

您可以使用 DataSource 屬性從 CSV 檔案讀取資料:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace YourNamespace
{
    [TestClass]
    public class CsvDataDrivenTest
    {
        public TestContext TestContext { get; set; }

        [TestMethod]
        [DataSource(
            "Microsoft.VisualStudio.TestTools.DataSource.CSV",
            "|DataDirectory|\\TestData.csv",
            "TestData#csv",
            DataAccessMethod.Sequential)]
        public void TestWithCsvDataSource()
        {
            // Access data from the current row
            int number = Convert.ToInt32(TestContext.DataRow["Number"]);
            string name = TestContext.DataRow["Name"].ToString();

            Console.WriteLine($"Number: {number}, Name: {name}");

            // Example assertions or logic
            Assert.IsTrue(number > 0);
            Assert.IsFalse(string.IsNullOrEmpty(name));
        }
    }
}

儲存和擷取運行時間數據

您可以使用 TestContext.Properties 來儲存可在相同測試工作階段中跨不同方法存取的自訂索引鍵/值組。

TestContext.Properties["MyKey"] = "MyValue";
string value = TestContext.Properties["MyKey"]?.ToString();

注意

從 MSTest 4.2 開始,來自 [TestCategory] 的測試類別已包含於 TestContext.Properties

從 MSTest 4.3 開始,在 TestContext.Properties[AssemblyInitialize] 中新增的自訂屬性會套用到組件中的每個類別和測試,而在 [ClassInitialize] 中新增的屬性則會套用到該類別中的每個測試。 這可讓夾具提供可供測試方法讀取的共用內容。

從 MSTest 4.3.3 開始, [TestProperty] 值、測試類別、主機提供的屬性以及測試新增的屬性都保留在該測試的範圍,不會流向同級測試。

從目前的呼叫堆疊存取 TestContext

從 MSTest 4.2 開始,在測試方法執行期間,TestContext.Current 可從呼叫堆疊中的任何位置傳回目前測試的 TestContext。 這個 API 是實驗性質,使用屬性 [Experimental] ,未來 MSTest 版本可能會有所變動。

將數據關聯至測試

TestContext.AddResultFile(String) 方法可讓您將檔案新增至測試結果,使其可在測試輸出中檢閱。 如果您在測試期間產生檔案(例如記錄檔、螢幕快照或數據檔),而您想要附加至測試結果,這非常有用。

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class TestClassResultFile
{
    public TestContext TestContext { get; set; }

    [TestMethod]
    public void TestMethodWithResultFile()
    {
        // Simulate creating a log file for this test
        string logFilePath = Path.Combine(TestContext.TestRunDirectory, "TestLog.txt");
        File.WriteAllText(logFilePath, "This is a sample log entry for the test.");

        // Add the log file to the test result
        TestContext.AddResultFile(logFilePath);

        // Perform some assertions (example only)
        Assert.IsTrue(File.Exists(logFilePath), "The log file was not created.");
        Assert.IsTrue(new FileInfo(logFilePath).Length > 0, "The log file is empty.");
    }
}

您也可以使用 TestContext.WriteTestContext.WriteLine 方法來直接將自定義訊息寫入測試輸出。 從 MSTest 4.4 開始, Live 輸出擷取模式在測試執行時會迴響這些訊息,並將它們附加到最終測試結果上。 欲了解更多資訊,請參閱 配置 MSTest 輸出

取消令牌

TestContext 會公開一個 CancellationToken 屬性,在測試逾時或測試執行中止時發出信號。 你應該把這個令牌傳遞給非同步操作,讓它們以協作方式回應取消。 這在使用 暫停 屬性時尤其重要。

TestContext 以屬性存取時:

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class TestClassCancellationToken
{
    // MSTest automatically sets the TestContext property before each test runs.
    // MSTest.Analyzers includes a diagnostic suppressor that removes CS8618
    // (non-nullable property uninitialized) for this property.
    public TestContext TestContext { get; set; }

    [TestMethod]
    [Timeout(5000, CooperativeCancellation = true)]
    public async Task MyAsyncTest()
    {
        using var client = new HttpClient();
        var response = await client.GetAsync(
            "https://example.com", TestContext.CancellationToken);

        Assert.IsTrue(response.IsSuccessStatusCode);
    }
}

TestContext 透過建構子注入時(MSTest 3.6+):

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class TestClassCancellationTokenCtor
{
    private readonly TestContext _testContext;

    public TestClassCancellationTokenCtor(TestContext testContext)
    {
        _testContext = testContext;
    }

    [TestMethod]
    [Timeout(5000, CooperativeCancellation = true)]
    public async Task MyAsyncTest()
    {
        using var client = new HttpClient();
        var response = await client.GetAsync(
            "https://example.com", _testContext.CancellationToken);

        Assert.IsTrue(response.IsSuccessStatusCode);
    }
}

小提示

MSTest 分析規則 MSTEST0049 幫助識別需要傳遞 TestContext.CancellationToken 的非同步呼叫。 它還提供一個程式碼修正器,能自動套用變更。

以下分析器有助於確保類別的 TestContext 正確使用:

  • MSTEST0005 - TestContext 屬性應該有有效的版面配置。
  • MSTEST0024 - 不要將 TestContext 儲存在靜態成員中。
  • MSTEST0033 - 抑制 CS8618 以取得 TestContext 屬性。
  • MSTEST0048 - 避免在夾具方法中使用 TestContext 屬性。
  • MSTEST0049 - 流程測試上下文取消標記。
  • MSTEST0054 - 使用 CancellationToken 屬性。