用 MSTest 和 Microsoft 測試 WinUI 3 應用程式。測試平台

用 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 產生第二個入口點,請設 GenerateTestingPlatformEntryPointfalse

新增套件參考至目前相容的 MSTestMicrosoft 版本。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 會注入其啟動初始化器:

  • WindowsPackageTypeNone
  • OutputTypeExeWinExe
  • WindowsAppSDKSelfContained 不是 true

如果不是 Windows 應用程式 SDK 應用程式的主機載入你的測試函式庫,請設WindowsAppSdkBootstrapInitializetrue「在函式庫中」。

Note

VSTest 不支援這種未封裝的 WinUI 設定。 用 MTP 來執行專案。

配置一個打包式的全信任測試應用程式

保留預設的 WinUI 配置:

  • 不要設定 WindowsPackageTypeNone
  • 保留 Package.appxmanifest 專案中的套件資產。
  • 設定 EnableMsixToolingtrue 如果你的專案使用單一專案的 MSIX 封裝工具。

當包含完全信任 MSIX 註冊與 AUMID 啟用的預覽版可用後,新增該特定版本的 Microsoft。Testing.Extensions.PackagedApp 套件。 不要用早期 1.0.0-alpha 的套件來做這個設定。

該套件的 MSBuild 道具透過 來註冊發射器 AddSelfRegisteredExtensions。 不要也打電話 AddPackagedAppDeployment。 MTP 執行只能註冊一個測試主機啟動器。

發射器執行以下動作:

  1. 它會檢查描述測試執行檔的 。AppxManifest.xml
  2. 它會將建置輸出配置登錄到 Windows。
  3. 它會從註冊包裹和清單應用程式 ID 解析應用程式的 AUMID。
  4. 它會透過 AUMID 啟動應用程式,並將已啟動的程序連接到 MTP 控制器。

啟動器會忽略祖先目錄中無關的清單,除非有 Application 條目指向測試執行檔。 未封裝且間接參考套件的應用程式會保留在直接啟動路徑上。

在執行打包測試應用程式前,先先符合以下要求:

  • 使用針對 Windows 的特定目標框架,平台版本10.0.19041.0或更新版本。
  • 若要註冊未簽名的建置輸出配置,請啟用開發者模式或設定側載。
  • 使用全信任的打包桌面應用程式。 這個擴充功能不支援 UWP 或其他 AppContainer 主機。

注意事項

Microsoft.Testing.Extensions.PackagedAppITestHostLauncher 延伸點則是實驗性質。 未來的版本可能會更改或移除他們的 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 專用的目標框架、開發者模式或側載設定、全信任應用程式模型,以及清單執行檔條目。

另請參閱