MSTest (Microsoft 測試架構) 是適用於 .NET 應用程式的測試架構。 它可讓您撰寫和執行測試,並提供與 Visual Studio 和 Visual Studio Code 測試總管、.NET CLI 和許多 CI 管線整合的測試套件。
MSTest 是完全支援、開放原始碼且跨平台的測試架構,可搭配 GitHub 上裝載且支援的所有 .NET 目標 (.NET Framework、.NET Core、.NET、UWP、WinUI 等) 運作。
運行設定
.runsettings 檔案可用來設定單元測試的執行方式。 若要深入了解與平台相關的 runsettings 和組態,請參閱 VSTest runsettings 文件或 MSTest 執行器 runsettings 文件。
平行化設定
要啟用 MSTest 組譯內平行化,請配置 Parallelize 下的 MSTest項目,包括其 Workers 與 Scope 值,詳見下一節表格。 若要強制關閉執行中的平行化,請設 <RunConfiguration><DisableParallelization>true</DisableParallelization></RunConfiguration>。
DisableParallelization 設定會覆寫 [assembly: Parallelize] 屬性。
關於平行化屬性的行為及每個組態機制的比較,請參見 「配置平行化」。
MSTest 元素
下列 runsettings 項目可讓您設定 MSTest 的行為方式。
| 組態 | 預設 | 價值觀 |
|---|---|---|
AssemblyCleanupTimeout |
沒有 | 全域指定逾時設定,套用於每個組件清理方法的執行個體。 在組件清理方法上指定的 [Timeout] 屬性會覆寫全域逾時設定。 |
AssemblyInitializeTimeout |
沒有 | 以全域方式指定要套用於每個組件初始化方法實例的超時。 在組件初始化方法上指定的 [Timeout] 屬性會覆寫全域逾時設定。 |
AssemblyResolution |
假的 | 您可以在求解及執行單元測試時,指定額外組件的路徑。 例如,您可以針對與測試組件位於不同目錄的相依性組件,使用這些路徑。 若要指定路徑,請使用目錄路徑項目。 路徑可以包括環境變數。<AssemblyResolution> <Directory path="D:\myfolder\bin\" includeSubDirectories="false"/> </AssemblyResolution>此功能只有在使用 .NET Framework 目標時才會套用。 |
CaptureAssertionFailureDiagnostics |
假的 | 從 MSTest 4.5 預覽版開始,當 MSTest 斷言失敗時,可擷取具大小限制的 JSON 診斷資料。 這些產物包括斷言值、來源框架、同時進行的測試以及程序狀態。 MSTest 會為每次測試嘗試的未成功結果附加最多三個擷取資料,並刪除通過結果的擷取資料。 UWP、WinUI、Native AOT 以及其他沒有動態程式碼的環境都不支援這個設定。 |
CaptureTraceOutput |
Result |
從 Trace.Write* 和 Console.Write* API 擷取文字,並將其與目前的測試建立關聯。 在 .NET 框架中,擷取也包含Debug.Write*透過共享追蹤監聽器。 現代 .NET 不會將 Debug.Write* 傳送至那些接聽程式,因此 MSTest 不會擷取到它。 從 MSTest 4.4 開始,請使用 None、 Result或 Live。
Live 也會在測試執行期間輸出 Console、Trace 和 TestContext.Write* 的內容。 早期的布林值仍被支援: true 映射到 Result,映射 false 到 None。 |
ClassCleanupLifecycle |
課程結束 | 如果你想讓類別清理在組裝結束時完成,請設定為 EndOfAssembly。 (自 MSTest v4 起不再支援,因為 EndOfClass 這是預設且唯一的 ClassCleanup 行為) |
ClassCleanupTimeout |
沒有 | 全域指定逾時,適用於每個類別的清除方法實例。 在類別的清理方法中指定的 [Timeout] 屬性會覆寫全域超時設定。 |
ClassInitializeTimeout |
沒有 | 以全域範圍指定逾時設定,以套用於每個類別初始化方法的實例。 在類別初始化方法中指定的 [Timeout] 屬性會覆蓋全域逾時設定。 |
ConsiderFixturesAsSpecialTests |
假的 | 如果要在 Visual Studio 和 Visual Studio Code AssemblyInitialize 和 AssemblyCleanup 記錄中將 ClassInitialize、ClassCleanup、Test Explorer、 顯示為個別項目,請將此值設定為 true |
DeleteDeploymentDirectoryAfterTestRunIsComplete |
真實 | 若要在測試回合之後保留部署目錄,請將此值設定為 false。 |
DeploymentEnabled |
真實 | 如果您將此值設定為 false,就不會將您在測試方法中所指定的部署項目複製到部署目錄中。 |
DeployTestSourceDependencies |
真實 | 一個值,指出是否要部署測試源參照。 |
EnableBaseClassTestMethodsFromOtherAssemblies |
真實 | 一個值,表示是否啟用從不同於繼承測試類別所在組件的基底類別中探索測試方法。 |
ForcedLegacyMode |
假的 | 舊版 Visual Studio 中的 MSTest 配接器已進行過最佳化,因此更快速且更具延展性。 某些行為 (例如測試執行順序) 可能與舊版 Visual Studio 稍有出入。 將此值設定為 true,以使用較舊的測試配接器。 例如,如果您為單元測試指定 app.config 檔案,則可以使用此設定。 建議您考慮重構測試,以便使用較新的配接器。 |
GlobalTestCleanupTimeout |
TestCleanupTimeout |
從 MSTest 4.4 開始,為每個全域測試清理方法指定逾時。 當你省略此條目時,MSTest 會使用 TestCleanupTimeout。 方法上的一個 [Timeout] 屬性會覆蓋兩個值。 |
GlobalTestInitializeTimeout |
TestInitializeTimeout |
從 MSTest 4.4 開始,為每個全域測試初始化方法指定逾時。 當你省略此條目時,MSTest 會使用 TestInitializeTimeout。 方法上的一個 [Timeout] 屬性會覆蓋兩個值。 |
LaunchDebuggerOnTestFailure |
假的 | 從 MSTest 4.2 開始,當設定為 true 時,MSTest 會在測試失敗時啟動除錯器。 |
MapInconclusiveToFailed |
假的 | 如果測試完成後狀態不明確,則會在 [測試總管] 中對應至略過狀態。 如果您要讓結果不明的測試顯示為 [失敗],請將此值設定為 true。 |
MapNotRunnableToFailed |
真實 | 一個值,指出無法執行的結果是否對應至失敗的測試。 |
OrderTestsByNameInClass |
假的 | 如果您要在 [測試總管] 和命令列中依測試名稱執行測試,請將此值設定為 true。 |
Parallelize |
用來設定平行處理設定:Workers: 用於平行化的執行緒/工作者數量,預設為 目前機器上的處理器數量。Scope:平行化的範圍。 您可以設定為 MethodLevel。 預設為ClassLevel。<Parallelize><Workers>32</Workers><Scope>MethodLevel</Scope></Parallelize> |
|
RandomizeTestOrder |
假的 | 從 MSTest 4.3 開始,將此值設 為 true ,以隨機順序執行測試,有助於揭示測試間隱藏的排序依賴關係。 此設定無法與 OrderTestsByNameInClass合併。 |
RandomTestOrderSeed |
從 MSTest 4.3 開始,當 RandomizeTestOrder為真時,設定整數種子,使隨機順序能在多次執行中重複出現。 當未設定時,每次運行會使用一個新的種子。 |
|
SettingsFile |
您可以指定與此處的 MS 測試配接器一起使用的測試設定檔。 您也可以從設定功能表指定測試設定檔。 如果你指定此值,也必須將 ForcedLegacyMode 設為 true。<ForcedLegacyMode>true</ForcedLegacyMode> |
|
TestCleanupTimeout |
沒有 | 以全域方式指定要套用於每個測試清理方法的超時時間。 在測試清除方法上指定的 [Timeout] 屬性將覆蓋全域逾時。 |
TestInitializeTimeout |
沒有 | 以全域方式指定要應用在每個測試初始化方法的執行個體上的逾時。 在測試初始化方法上指定的 [Timeout] 屬性會覆寫整體逾時設定。 |
TestTimeout |
沒有 | 取得指定的全域測試案例超時。 |
TreatClassAndAssemblyCleanupWarningsAsErrors |
假的 | 若要將類別清除中的失敗視為錯誤,請將此值設定為 true。 |
TreatDiscoveryWarningsAsErrors |
假的 | 若要將測試探索警告報告為錯誤,請將此值設定為 [true]。 |
超時值必須是以毫秒為單位的正整數。 若要在不設逾時的情況下執行,請省略該項目,而不要將其設為 0。 全域測試固定裝置逾時會繼承對應的 TestInitializeTimeout 或 TestCleanupTimeout 值。
TestRunParameter 元素
<TestRunParameters>
<Parameter name="webAppUrl" value="http://localhost" />
</TestRunParameters>
測試執行參數提供了定義執行時可供測試使用的變數與值的方法。 使用 MSTest TestContext.Properties 屬性存取參數:
private string _appUrl;
public TestContext TestContext { get; set; }
[TestMethod]
public void HomePageTest()
{
string _appUrl = TestContext.Properties["webAppUrl"];
}
若要使用測試回合參數,請將公用 TestContext 屬性新增至您的測試類別。
.runsettings 檔案範例
下列 XML 顯示一般 .runsettings 檔案的內容。 複製此程式碼,並根據需求編輯。
檔案的每個項目都有預設值,因此為選擇性。
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<!-- Parameters used by tests at runtime -->
<TestRunParameters>
<Parameter name="webAppUrl" value="http://localhost" />
<Parameter name="webAppUserName" value="Admin" />
<Parameter name="webAppPassword" value="Password" />
</TestRunParameters>
<!-- MSTest -->
<MSTest>
<MapInconclusiveToFailed>True</MapInconclusiveToFailed>
<CaptureTraceOutput>false</CaptureTraceOutput>
<DeleteDeploymentDirectoryAfterTestRunIsComplete>False</DeleteDeploymentDirectoryAfterTestRunIsComplete>
<DeploymentEnabled>False</DeploymentEnabled>
<ConsiderFixturesAsSpecialTests>False</ConsiderFixturesAsSpecialTests>
<AssemblyResolution>
<Directory path="D:\myfolder\bin\" includeSubDirectories="false"/>
</AssemblyResolution>
</MSTest>
</RunSettings>
testconfig.json
使用 MSTest 執行測試時,您可以使用 testconfig.json 檔案來設定測試執行器的行為。
testconfig.json 檔案是 JSON 檔案,其中包含測試執行器的組態設定。 檔案是用來設定測試執行器和測試執行環境。 欲了解更多資訊,請參閱 MTP testconfig.json 文件。
從 MSTest 3.7 開始,您也可以在相同的組態檔中設定 MSTest 執行。 下列各節說明您可以在 testconfig.json 檔案中使用的設定。
從 MSTest 4.3.3 開始,.NET Framework 執行環境也支援在 testconfig.json 中使用註解和結尾逗號。
MSTest 元素
MSTest 設定會依下列各節中所述的功能分組。
| 進入 | 預設 | 描述 |
|---|---|---|
| 啟用來自其他程序集的基類測試方法 | 真實 | 一個值,表示是否啟用從不同於繼承測試類別所在組件的基底類別中探索測試方法。 |
| classCleanupLifecycle | 組裝完成 | 如果您要在類別結尾進行類別清除,請將它設定為 EndOfClass。 |
assemblyResolution 設定
本節中的所有設定都屬於 assemblyResolution 元素。
| 進入 | 預設 | 描述 |
|---|---|---|
| 路徑 | 沒有 | 您可以在求解及執行單元測試時,指定額外組件的路徑。 例如,您可以針對與測試組件位於不同目錄的相依性組件,使用這些路徑。 您可以為圖形 { "path": "...", "includeSubDirectories": "true/false" }指定路徑。 |
例:
{
"mstest": {
"assemblyResolution": {
{ "path": "...", "includeSubDirectories": "true/false" }
}
}
}
deployment 設定
本節中的所有設定都屬於 deployment 元素。
| 進入 | 預設 | 描述 |
|---|---|---|
| 測試運行完成後刪除部署目錄 | 真實 | 若要在測試回合之後保留部署目錄,請將此值設定為 false。 |
| deployTestSourceDependencies (部署測試源代碼的依賴項) | 真實 | 指示是否要部署測試來源的參考資料。 |
| 啟用 | 真實 | 如果您將此值設定為 false,就不會將您在測試方法中所指定的部署項目複製到部署目錄中。 |
例:
{
"mstest": {
"deployment": {
"deleteDeploymentDirectoryAfterTestRunIsComplete": true,
"deployTestSourceDependencies": true,
"enabled": true
}
}
}
output 設定
本節中的所有設定都屬於 output 元素。
| 進入 | 預設 | 描述 |
|---|---|---|
| captureTrace | Result |
擷取 Console 並 Trace 輸出,並將其與當前測試關聯起來。 在 .NET Framework 中,擷取也包含透過共享追蹤監聽器輸出的 Debug。 現代的 .NET Debug.Write* 輸出不會被捕捉。 從 MSTest 4.4 開始,請使用 None、 Result或 Live。
Live 也會在測試執行期間顯示輸出內容,包括 TestContext.Write* 訊息。 布林值仍受支援:true 會映射到 Result,而 false 會映射到 None。 |
例:
{
"mstest": {
"output": {
"captureTrace": false
}
}
}
parallelism 設定
本節中的所有設定都屬於 parallelism 元素。
關於平行化屬性的行為及每個組態機制的比較,請參見 「配置平行化」。
| 進入 | 預設 | 描述 |
|---|---|---|
| 啟用 | 假的 | 啟用測試平行處理。 |
| 範圍 | 類別 | 平行處理的範圍。 您可以設定為 method。 默認的 class會對應至循序執行指定類別的所有測試,但平行執行多個類別。 |
| 工人 | 0 | 要用於平行處理的線程/工作執行緒數量。 預設值會對應至目前電腦上的處理器數目。 |
例:
{
"mstest": {
"parallelism": {
"enabled": true,
"scope": "method",
"workers": 32
}
}
}
execution 設定
本節中的所有設定都屬於 execution 元素。
| 進入 | 預設 | 描述 |
|---|---|---|
| considerEmptyDataSourceAsInconclusive(將空數據源視為不確定) | 假的 | 當設定為 true時,空的數據源會被視為不確定。 |
| 將固定裝置視為特殊測試 | 假的 | 若要在 Visual Studio 和 Visual Studio Code AssemblyInitialize 和 AssemblyCleanup 記錄檔中,將 ClassInitialize、ClassCleanup、Test Explorer、 顯示為個別專案,請將此值設定為 true 。 |
| 擷取斷言失敗診斷資訊 | 假的 | 從 MSTest 4.5 預覽版開始,每次測試嘗試最多可捕捉三個 JSON 斷言失敗診斷產物。 此設定對應至 .runsettings 中的 CaptureAssertionFailureDiagnostics。 |
| 依賴 | 從 MSTest 4.4 開始,宣告測試依賴性 chains 和 nodes。 此設定僅適用於 Microsoft.Testing.Platform。 欲了解更多資訊,請參閱 測試相依關係。 |
|
| 將不確定映射為失敗 | 假的 | 如果測試完成後狀態不明確,則會在 [測試總管] 中對應至略過狀態。 如果您要讓結果不明的測試顯示為 [失敗],請將此值設定為 true。 |
| 在測試失敗時啟動偵錯工具 | 假的 | 從 MSTest 4.2 開始,當設定為 true時,MSTest 在測試失敗時啟動除錯器。 |
| 將不可執行映射為失敗 | 真實 | 一個值,指出無法執行的結果是否對應至失敗的測試。 |
| 按名稱排序的測試在類別中 | 假的 | 在每個班級內依字母順序進行測試。 從 MSTest 4.3 開始,請使用 mstest.execution.orderTestsByNameInClass。 較早版本的 mstest.orderTestsByNameInClass 金鑰仍可運作,但會產生棄用警告。 |
| 隨機化測試順序 | 假的 | 從 MSTest 4.3 開始,將此值 true 設為隨機順序執行測試,有助於揭示測試間隱藏的排序依賴關係。 此設定無法與 orderTestsByNameInClass合併。 |
| randomTestOrderSeed | 從 MSTest 4.3 開始,當 randomizeTestOrder 為 true 時,設定整數種子,讓隨機順序可在多次執行之間重現。 當未設定時,每次運行會使用一個新的種子。 |
|
| treatClassAndAssemblyCleanupWarningsAsErrors (視類別與組件清理警告為錯誤) | 假的 | 若要將類別清除中的失敗視為錯誤,請將此值設定為 true。 |
| 將探索警告視為錯誤 | 假的 | 若要將測試探索警告報告為錯誤,請將此值設定為 [true]。 |
例:
{
"mstest": {
"execution": {
"considerEmptyDataSourceAsInconclusive": false,
"considerFixturesAsSpecialTests": false,
"mapInconclusiveToFailed": true,
"mapNotRunnableToFailed": true,
"treatClassAndAssemblyCleanupWarningsAsErrors": false,
"treatDiscoveryWarningsAsErrors": false
}
}
}
產生的檔案名稱包括 mstest-assertion-failure-state-attempt-1-invocation-1-capture-1.json。 診斷是盡力而為,絕不會替換或隱藏原始斷言失敗。
Important
斷言失敗的診斷產物可以包含原始檔案路徑、測試名稱、斷言值以及程序元資料。 如果你將這些檔案作為 CI 產出物發佈,請限制存取權限,並使用符合你需求的最短保留期限。
timeout 設定
本節中的所有設定都屬於 timeout 元素。
| 進入 | 預設 | 描述 |
|---|---|---|
| 組裝清理 | 沒有 | 全域指定逾時設定,套用於每個組件清理方法的執行個體。 |
| 組件初始化 | 沒有 | 以全域方式指定要套用於每個組件初始化方法實例的超時。 |
| 類別清理 | 沒有 | 全域指定逾時,適用於每個類別的清除方法實例。 |
| 類別初始化 | 沒有 | 以全域範圍指定逾時設定,以套用於每個類別初始化方法的實例。 |
| globalTestCleanup | testCleanup |
從 MSTest 4.4 開始,為每個全域測試清理方法指定逾時。 當你省略此條目時,MSTest 會使用 testCleanup。 |
| globalTestInitialize | testInitialize |
從 MSTest 4.4 開始,為每個全域測試初始化方法指定逾時。 當你省略此條目時,MSTest 會使用 testInitialize。 |
| 測試 | 沒有 | 全球指定測試逾時時間。 |
| testCleanup | 沒有 | 以全域方式指定要套用於每個測試清理方法的超時時間。 |
| testInitialize | 沒有 | 以全域方式指定要應用在每個測試初始化方法的執行個體上的逾時。 |
| useCooperativeCancellation (協作取消功能) | 假的 | 當設定為 true時,如果逾時,MSTest 只會觸發 CancellationToken 的取消,但不會停止觀察該方法。 此行為效能更佳,但依賴用戶確保令牌正確地傳遞經過所有路徑。 |
注意
超時值必須是以毫秒為單位的正整數。 若要在不設逾時的情況下執行,請省略該項目,而不要將其設為 0。 全域測試夾具的逾時會繼承對應的 testInitialize 或 testCleanup 值,因此如果你不想為全域夾具設定逾時,就省略這兩個項目。 方法上的 [Timeout] 屬性會覆寫已設定的逾時值。
例:
{
"mstest": {
"timeout": { "globalTestInitialize": 30000, "globalTestCleanup": 30000 }
}
}
範例 testconfig.json 檔案
下列 JSON 顯示一般 .testconfig.json 檔案的內容。 複製此程式碼,並根據需求編輯。
檔案的每個項目都有預設值,因此為選擇性。
{
"platformOptions": {
"resultDirectory": "./TestResults"
},
"mstest": {
"execution": {
"mapInconclusiveToFailed": true,
"disableAppDomain": true,
"considerFixturesAsSpecialTests": false
},
"parallelism": {
"enabled": true,
"scope": "method"
},
"output": {
"captureTrace": false
}
}
}
MSBuild 屬性
從 MSTest 4.3 開始,你可以透過專案檔或 Directory.Build.props 啟用組件層級的平行化,而不需要撰寫 [assembly: Parallelize] 屬性。 這些屬性會在建置期間產生對應的組件屬性,因此必須將 GenerateAssemblyInfo 設為 true(這是 SDK 樣式專案的預設值)。
關於產生屬性的行為及每個組態機制的比較,請參見 「配置平行化」。
| Property | 預設 | 描述 |
|---|---|---|
MSTestParallelizeScope |
平行化範圍。 將其設為 MethodLevel 或 ClassLevel,以輸出 [assembly: Parallelize(Scope = ExecutionScope.MethodLevel)](或 ExecutionScope.ClassLevel);或將其設為 None,以輸出 [assembly: DoNotParallelize]。 |
|
MSTestParallelizeWorkers |
最大工作執行緒數,以 Workers 的 [assembly: Parallelize]值 表示。 一個 0 值對應到目前機器上的處理器數量。 當 MSTestParallelizeScope 是 None時,這個屬性無法設定。 |
MSTest 在建置過程中會驗證這兩個屬性。 無效的範圍值、非整數的工作程序數量,以及與 None 範圍併用的工作程序數量,都會導致建置失敗。 不要同時宣告 [assembly: Parallelize] 或 [assembly: DoNotParallelize] 在原始碼,因為產生的屬性會重複它。 當 GenerateAssemblyInfo 是 false時,則改為宣告原始碼中的屬性。
以下範例允許每個匯入 Directory.Build.props 該檔案的測試專案使用四個工作者,進行方法層級的平行化:
<Project>
<PropertyGroup>
<MSTestParallelizeScope>MethodLevel</MSTestParallelizeScope>
<MSTestParallelizeWorkers>4</MSTestParallelizeWorkers>
</PropertyGroup>
</Project>