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 提供測試回合的相關信息,例如:
- TestContext.TestName – 目前執行中測試的名稱。
- TestContext.CurrentTestOutcome - 目前測試結果。
- TestContext.FullyQualifiedTestClassName - 測試類別的完整名稱。
- TestContext.TestRunDirectory - 執行測試回合的目錄。
-
TestContext.DeploymentDirectory - 部署專案所在的目錄。 要填充此目錄,請使用
DeploymentItemAttribute。 - TestContext.ResultsDirectory - 儲存測試結果的目錄。 通常是 TestContext.TestRunDirectory的子目錄。
- TestContext.TestRunResultsDirectory - 儲存測試結果的目錄。 通常是 TestContext.ResultsDirectory的子目錄。
- TestContext.TestResultsDirectory - 儲存測試結果的目錄。 通常是 TestContext.ResultsDirectory的子目錄。
- 從 MSTest 3.9 開始, TestContext.TestRunCount - 即目前測試執行的次數,從 1 開始。 當使用
[Retry]重試測試時,此值會大於 1。
每測試暫存目錄
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_RETAIN為1true或保留所有結果的目錄。
當測試通過時,從 為 AddResultFile的目錄註冊檔案,MSTest 會保留該目錄,直到主機收集附件。 清理是盡力而為,不會改變測試結果。
TestTempDirectory可用於 .NET 和 .NET Framework 目標,但不適用於 UWP 或 WinUI 目標。 這個屬性不會改變程序目前的目錄。
在 MSTest 3.7 和更新版本中,TestContext 類別也提供有助於 TestInitialize 和 TestCleanup 方法的新屬性:
-
TestContext.TestData - 將提供給參數化測試方法的數據,如果測試未參數化,則
null。 - TestContext.TestDisplayName - 測試方法的顯示名稱。
-
TestContext.TestException - 測試方法或測試初始化所擲回的例外狀況,如果測試方法未擲回例外狀況,則為
null。
數據驅動測試
在 MSTest 3.7 和更新版本中,屬性 TestContext.TestData 可用來存取 TestInitialize 和 TestCleanup 方法期間目前測試的數據。
以 .NET Framework 為目標時,TestContext 可讓您使用 DataRow 和 DataConnection 等屬性,擷取和設定資料驅動測試中每次迭代的資料(適用於 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.Write 或 TestContext.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 屬性。