用 Microsoft。Testing.Platform (MTP) 用來在 WinUI 3 應用程式中執行 MSTest 測試。 WinUI 應用程式作為測試主機。 它擁有應用程式的入口點、UI 執行緒和程序壽命。
請從兩種 WinUI 3 部署模型中選擇:
- 未封裝的應用程式會以一般的 Windows 執行檔形式執行。
-
封裝式全信任應用程式會保留 MSIX 套件身份,並利用實驗
Microsoft.Testing.Extensions.PackagedApp性擴充功能註冊並啟用測試主機。
Important
打包式應用程式擴充功能支援全信任的打包桌面應用程式。 它不支援 UWP 或其他 AppContainer 測試主機。
套件式全信任 AUMID 啟用已在 microsoft/testfx 倉庫中實作,但截至 2026 年 8 月 6 日,尚未在公開的 NuGet 套件中提供。 目前1.0.0-alpha的套件並不包含 Windows 專屬的啟用實作。 只有在套件釋出支援完全信任 MSIX 註冊及 AUMID 啟用後,才使用套件設定。
選擇部署模式
在設定測試專案前,先選擇部署模式。
| 需求 | 選擇 | 測試主機啟動 |
|---|---|---|
| 你的測試不需要套件身份,也不需要需要套件身份的 API。 | 未包裝 | MTP 會直接啟動應用程式執行檔。 |
| 你的測試需要 MSIX 套件身份或套件應用程式行為。 | MTP 預覽公開後,打包成完全信任 | 打包的應用程式擴充功能會註冊建置輸出,並透過應用程式使用者模型識別碼(AUMID)啟動應用程式。 |
| 你的測試必須在 UWP 或其他 AppContainer 中執行。 | VSTest | MTP 的 packaged-app 擴充功能不支援 AppContainer 隔離。 |
除非你的測試需要套件身份,否則建議使用未封裝的應用程式。 未封裝模型不需要套件註冊、開發者模式或實驗性的套件應用程式擴充功能。
在公開 MTP 預覽包含全信任 MSIX 註冊及 AUMID 啟用之前,請使用 VSTest 進行打包的全信任 WinUI 3 測試。
了解UWP邊界
不要把 UWP 當成另一個打包的 WinUI 3 模型。 既有針對 UAP 10 的經典 UWP 專案,也有設定在 true AppContainer 執行的現代 .NET UWP 專案UseUwp。 打包 WinUI 3 桌面應用程式並不會把它放進那個應用程式模型。
經典 UWP 和現代 .NET UWP 測試都可以使用 VSTest。 MTP 打包式應用程式啟動器針對全信任封裝桌面主機。 它無法將啟用參數或控制器連線傳送到 AppContainer 主機。
關於現代的 .NET UWP 配置,請參閱 MSTest .NET 9 UWP 範例。
設定 WinUI 測試主機
兩種部署模式都使用相同的自架型 MTP 架構。
設定共用專案屬性
在 WinUI 測試專案中設定以下屬性:
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<UseWinUI>true</UseWinUI>
<EnableMSTestRunner>true</EnableMSTestRunner>
<GenerateTestingPlatformEntryPoint>false</GenerateTestingPlatformEntryPoint>
請使用 .NET 8 或支援的 .NET 版本。 此範例針對 Windows 平台版本10.0.19041.0。 打包的應用程式擴充功能需要此版本或更新版本。
保留指向你測試應用程式 XAML 檔案的 WinUI ApplicationDefinition 項目。 WinUI 會從該項目產生一個入口點。 為防止 MTP 產生第二個入口點,請設 GenerateTestingPlatformEntryPoint 為 false。
新增套件參考至目前相容的 MSTest 與 Microsoft 版本。WindowsAppSDK。
應用程式中的主機 MTP
在 WinUI Application 類別中覆寫OnLaunched。 建立並啟用測試視窗,然後發布其調度器佇列:
_window = new UnitTestAppWindow();
_window.Activate();
UITestMethodAttribute.DispatcherQueue = _window.DispatcherQueue;
加上 using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; 。UITestMethodAttribute
從命令列參數建立 MTP 應用程式。 接著註冊 MSBuild 提供的擴充功能:
string[] cliArgs = Environment.GetCommandLineArgs().Skip(1)
.Where(arg => !arg.Contains("EnableMSTestRunner")).ToArray();
ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(cliArgs);
builder.AddSelfRegisteredExtensions(cliArgs);
using ITestApplication app = await builder.BuildAsync();
新增 using Microsoft.Testing.Platform.Builder; MTP建構器類型。 WinUI 建置會 EnableMSTestRunner 加入程序參數。 因為它不是 MTP 命令列選項,請在建立測試應用程式前移除它。
專案會停用產生的 MTP 入口點,因此呼叫 AddSelfRegisteredExtensions。 對於已打包的應用程式,這個方法也會註冊 Microsoft.Testing.Extensions.PackagedApp 啟動器。
在 OnLaunched中,將測試應用程式的建立與執行放入一個 try 區塊中。 將 的 await app.RunAsync() 結果 指派到 Environment.ExitCode。 在區 finally 塊中,關閉視窗並呼叫應用程式 Exit 的方法。
生命週期步驟提供兩項保證:
- 程序會回傳 MTP 退出代碼,因此測試失敗時會產生非零的程序退出代碼。
- WinUI 訊息迴圈會在執行後停止,而不是讓測試程序保持活躍。
Warning
不要加入 [assembly: WinUITestTarget(...)] 自架的 WinUI 測試應用程式。 這個屬性會啟動一個獨立測試主機的 WinUI 應用程式。 自架應用程式會先呼叫 Application.Start 。 屬性接著嘗試在同一程序中啟動第二個應用程式。
完整實作請參閱 未封裝的 WinUI 範例 與 WinUI 範例。
對 UI 執行緒執行測試
用於 UITestMethod 建立或存取 WinUI 物件的測試。 MSTest 會在你指派的 OnLaunched調度員隊列中排程測試。
[UITestMethod]
public void CreatesControlOnUiThread()
{
var grid = new Grid();
Assert.IsTrue(grid.DispatcherQueue.HasThreadAccess);
}
一般 TestMethod 程式不會在 WinUI 調度器隊列中執行。 用它來測試不需要 UI 執行緒的測試。
設定一個未封裝的測試應用程式
對於未封裝的應用程式,請新增以下屬性:
<WindowsPackageType>None</WindowsPackageType>
<EnableMsixTooling>false</EnableMsixTooling>
不要引用 Microsoft.Testing.Extensions.PackagedApp。 未封裝的應用程式在輸出中沒有 MSIX 身份, AppxManifest.xml 因此 MTP 可以直接啟動其執行檔。
預設情況下,當專案符合以下條件時,Windows 應用程式 SDK 會注入其啟動初始化器:
-
WindowsPackageType是None。 -
OutputType是Exe或WinExe。 -
WindowsAppSDKSelfContained不是true。
如果不是 Windows 應用程式 SDK 應用程式的主機載入你的測試函式庫,請設WindowsAppSdkBootstrapInitialize為true「在函式庫中」。
Note
VSTest 不支援這種未封裝的 WinUI 設定。 用 MTP 來執行專案。
配置一個打包式的全信任測試應用程式
保留預設的 WinUI 配置:
- 不要設定
WindowsPackageType為None。 - 保留
Package.appxmanifest專案中的套件資產。 - 設定
EnableMsixTooling為true如果你的專案使用單一專案的 MSIX 封裝工具。
當包含完全信任 MSIX 註冊與 AUMID 啟用的預覽版可用後,新增該特定版本的 Microsoft。Testing.Extensions.PackagedApp 套件。 不要用早期 1.0.0-alpha 的套件來做這個設定。
該套件的 MSBuild 道具透過 來註冊發射器 AddSelfRegisteredExtensions。 不要也打電話 AddPackagedAppDeployment。 MTP 執行只能註冊一個測試主機啟動器。
發射器執行以下動作:
- 它會檢查描述測試執行檔的 。
AppxManifest.xml - 它會將建置輸出配置登錄到 Windows。
- 它會從註冊包裹和清單應用程式 ID 解析應用程式的 AUMID。
- 它會透過 AUMID 啟動應用程式,並將已啟動的程序連接到 MTP 控制器。
啟動器會忽略祖先目錄中無關的清單,除非有 Application 條目指向測試執行檔。 未封裝且間接參考套件的應用程式會保留在直接啟動路徑上。
在執行打包測試應用程式前,先先符合以下要求:
- 使用針對 Windows 的特定目標框架,平台版本
10.0.19041.0或更新版本。 - 若要註冊未簽名的建置輸出配置,請啟用開發者模式或設定側載。
- 使用全信任的打包桌面應用程式。 這個擴充功能不支援 UWP 或其他 AppContainer 主機。
注意事項
Microsoft.Testing.Extensions.PackagedApp 而 ITestHostLauncher 延伸點則是實驗性質。 未來的版本可能會更改或移除他們的 API 和行為。 在使用套件模型進入生產測試基礎設施前,先評估風險。
執行測試
從包含 WinUI 測試專案的目錄中執行:
dotnet run
若要指定專案,請使用 dotnet run --project .\WinUITests.csproj。
對於未封裝的應用程式,MTP 會直接啟動執行檔。 對於已打包的應用程式,打包應用程式啟動器會註冊版面並以 AUMID 啟動應用程式。
在這兩種模型中,測試視窗會打開,MTP 執行測試,視窗會關閉。 終端機接著回報測試摘要。 成功執行時會以代碼 0. 當測試失敗時, OnLaunched 將非零 RunAsync 結果指派給 Environment.ExitCode。
兩種型號都可以用 dotnet run 。 若要直接執行未封裝的應用程式,請使用已產生的應用程式執行檔。 不要用 dotnet exec ,因為 WinUI 會根據流程路徑解析 PRI 資源。
排除設定問題
請使用以下檢查來檢查最常見的設定失敗:
| 癥狀 | 檢查 |
|---|---|
應用程式會回報多通電話給 Application.Start。 |
從自架測試應用程式中移除該 WinUITestTarget 屬性。 |
| 測試運行結束了,但流程仍然開放。 | 關閉測試視窗,並在 RunAsync之後呼叫Exit一個finally區塊。 |
測試失敗後,仍然會回傳程序退出碼 0。 |
將 的 RunAsync 結果 指派到 Environment.ExitCode。 |
未封裝的執行失敗是因為 AppxManifest.xml 缺少。 |
確認專案啟用 MTP,且該執行沒有使用 VSTest。 |
| 包裝版的 run 無法註冊或啟用該應用程式。 | 確認 Windows 專用的目標框架、開發者模式或側載設定、全信任應用程式模型,以及清單執行檔條目。 |