Testen Sie WinUI 3-Apps mit MSTest und Microsoft. Testing.Platform

Verwenden Sie Microsoft. Testing.Platform (MTP) zum Ausführen von MSTest-Tests in einer WinUI 3-App. Die WinUI-App fungiert als Testhost. Sie besitzt den Einstiegspunkt der Anwendung, den UI-Thread und die Prozesslebensdauer.

Wählen Sie zwischen zwei WinUI 3-Bereitstellungsmodellen aus:

  • Eine entpackte App wird als normale Windows ausführbare Datei ausgeführt.
  • Eine verpackte voll vertrauenswürdige App behält die MSIX-Paketidentität bei und verwendet die experimentelle Microsoft.Testing.Extensions.PackagedApp Erweiterung, um den Testhost zu registrieren und zu aktivieren.

Important

Die Paket-App-Erweiterung unterstützt voll vertrauenswürdige verpackte Desktop-Apps. UWP oder andere AppContainer-Testhosts werden nicht unterstützt.

Die voll vertrauenswürdige AUMID-Aktivierung wird im microsoft/testfx Repository implementiert, ist aber ab dem 6. August 2026 nicht in einem öffentlichen NuGet-Paket verfügbar. Die aktuellen 1.0.0-alpha Pakete enthalten nicht die Windows-spezifische Aktivierungsimplementierung. Verwenden Sie das verpackte Setup nur, nachdem eine Paketversion die Unterstützung für die voll vertrauenswürdige MSIX-Registrierung und die AUMID-Aktivierung identifiziert.

Auswählen eines Bereitstellungsmodells

Wählen Sie das Bereitstellungsmodell aus, bevor Sie das Testprojekt konfigurieren.

Anforderung Auswählen Testen des Hoststarts
Ihre Tests benötigen keine Paketidentität oder APIs, die paketidentität erfordern. Unverpackt MTP startet die ausführbare App direkt.
Für Ihre Tests ist das MSIX-Paketidentitäts- oder Paket-App-Verhalten erforderlich. Verpackt voll vertrauenswürdig, nachdem die MTP-Vorschau öffentlich verfügbar ist Die App-Erweiterung registriert die Buildausgabe und aktiviert die App anhand der Anwendungsbenutzermodell-ID (Application User Model ID, AUMID).
Ihre Tests müssen in UWP oder einem anderen AppContainer ausgeführt werden. VSTest Die MTP-App-Erweiterung unterstützt keine AppContainer-Isolation.

Verwenden Sie eine entpackte App, es sei denn, Ihre Tests erfordern eine Paketidentität. Das entpackte Modell erfordert keine Paketregistrierung, den Entwicklermodus oder die experimentelle Paket-App-Erweiterung.

Bis eine öffentliche MTP-Vorschau voll vertrauenswürdige MSIX-Registrierung und AUMID-Aktivierung umfasst, verwenden Sie VSTest für voll vertrauenswürdige WinUI 3-Tests.

Grundlegendes zur UWP-Grenze

Behandeln Sie UWP nicht als ein anderes verpacktes WinUI 3-Modell. Sowohl klassische UWP-Projekte für UAP 10 als auch moderne .NET UWP-Projekte, die für die true Ausführung in einem AppContainer festgelegt sindUseUwp. Das Verpacken einer WinUI 3-Desktop-App platziert sie nicht in diesem App-Modell.

Verwenden Sie VSTest für klassische UWP- und moderne .NET UWP-Tests. Das MTP-Startprogramm für verpackte Apps zielt auf voll vertrauenswürdige verpackte Desktophosts ab. Die Aktivierungsargumente oder Controllerverbindung kann nicht an einen AppContainer-Host übergeben werden.

Eine moderne .NET UWP-Konfiguration finden Sie im BEISPIEL "MSTest .NET 9 UWP".

Konfigurieren des WinUI-Testhosts

Beide Bereitstellungsmodelle verwenden dasselbe selbst gehostete MTP-Setup.

Festlegen der allgemeinen Projekteigenschaften

Legen Sie diese Eigenschaften im WinUI-Testprojekt fest:

<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<UseWinUI>true</UseWinUI>
<EnableMSTestRunner>true</EnableMSTestRunner>
<GenerateTestingPlatformEntryPoint>false</GenerateTestingPlatformEntryPoint>

Verwenden Sie .NET 8 oder höher unterstützte .NET Version. Das Beispiel zielt auf Windows Plattformversion ab10.0.19041.0. Für die Paket-App-Erweiterung ist diese Version oder höher erforderlich.

Behalten Sie das WinUI-Element ApplicationDefinition bei, das auf die XAML-Datei Ihrer Test-App verweist. WinUI generiert einen Einstiegspunkt aus diesem Element. Um zu verhindern, dass MTP einen zweiten Einstiegspunkt generiert, legen Sie diesen GenerateTestingPlatformEntryPoint auf false.

Fügen Sie Paketverweise zu den aktuellen kompatiblen Versionen von MSTest und Microsoft hinzu. WindowsAppSDK.

Hosten von MTP aus der Anwendung

Überschreiben OnLaunched sie in der WinUI-Klasse Application . Erstellen und aktivieren Sie das Testfenster, und veröffentlichen Sie dann die Verteilerwarteschlange:

_window = new UnitTestAppWindow();
_window.Activate();
UITestMethodAttribute.DispatcherQueue = _window.DispatcherQueue;

Hinzufügen using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; für UITestMethodAttribute.

Erstellen Sie die MTP-Anwendung aus den Befehlszeilenargumenten. Registrieren Sie dann die Erweiterungen, die MSBuild beiträgt:

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();

Fügen Sie für die MTP-Generatortypen hinzu using Microsoft.Testing.Platform.Builder; . Der WinUI-Build fügt EnableMSTestRunner die Prozessargumente hinzu. Da es sich nicht um eine MTP-Befehlszeilenoption handelt, entfernen Sie sie, bevor Sie die Testanwendung erstellen.

Das Projekt deaktiviert den generierten MTP-Einstiegspunkt, also aufrufen AddSelfRegisteredExtensions. Bei einer verpackten App registriert die Methode auch das Microsoft.Testing.Extensions.PackagedApp Startprogramm.

Setzen OnLaunchedSie die Testanwendungserstellung und -ausführung in einen try Block. Zuweisen des Ergebnisses zu await app.RunAsync()Environment.ExitCode. Schließen Sie in einem finally Block das Fenster, und rufen Sie die Methode der Anwendung Exit auf.

Die Lebenszyklusschritte bieten zwei Garantien:

  • Der Prozess gibt den MTP-Beendigungscode zurück, daher erzeugt ein fehlgeschlagener Test einen Nichtzero-Prozess-Exitcode.
  • Die WinUI-Nachrichtenschleife wird nach der Ausführung beendet, anstatt den Testprozess aktiv zu lassen.

Warning

Fügen Sie nicht zu einer selbst gehosteten WinUI-Test-App hinzu [assembly: WinUITestTarget(...)] . Das Attribut startet eine WinUI-Anwendung für einen separaten Testhost. Eine selbst gehostete App ruft zuerst auf Application.Start . Das Attribut versucht dann, eine zweite Anwendung im selben Prozess zu starten.

Eine vollständige Implementierung finden Sie im entpackten WinUI-Beispiel und im gepackten WinUI-Beispiel.

Ausführen von Tests im UI-Thread

Wird für einen Test verwendet UITestMethod , der WinUI-Objekte erstellt oder darauf zugreift. MSTest plant den Test in der Dispatcher-Warteschlange, die Sie während OnLaunchedder Zuweisung zugewiesen haben.

[UITestMethod]
public void CreatesControlOnUiThread()
{
    var grid = new Grid();
    Assert.IsTrue(grid.DispatcherQueue.HasThreadAccess);
}

Eine normale TestMethod Ausführung wird nicht in der WinUI-Verteilerwarteschlange ausgeführt. Verwenden Sie sie für Tests, für die der UI-Thread nicht erforderlich ist.

Konfigurieren einer entpackten Test-App

Fügen Sie für eine entpackte App die folgenden Eigenschaften hinzu:

<WindowsPackageType>None</WindowsPackageType>
<EnableMsixTooling>false</EnableMsixTooling>

Verweisen Sie nicht auf Microsoft.Testing.Extensions.PackagedApp. Die entpackte App hat keine MSIX-Identität oder AppxManifest.xml in der Ausgabe, sodass MTP die ausführbare Datei direkt starten kann.

Standardmäßig fügt die Windows App SDK den Bootstrap-Initialisierer ein, wenn das Projekt die folgenden Bedingungen erfüllt:

  • WindowsPackageType ist None.
  • OutputType ist Exe oder WinExe.
  • WindowsAppSDKSelfContained ist nicht true.

Wenn ein Host, der keine Windows App SDK App ist, Ihre Testbibliothek lädt, legen Sie sie in der Bibliothek fest WindowsAppSdkBootstrapInitializetrue.

Note

VSTest unterstützt diese entpackte WinUI-Konfiguration nicht. Führen Sie das Projekt mit MTP aus.

Konfigurieren einer verpackten voll vertrauenswürdigen Test-App

Behalten Sie die Standardmäßige WinUI-Konfiguration bei:

  • Setzen Sie WindowsPackageType nicht auf None.
  • Behalten Sie Package.appxmanifest die Paketressourcen im Projekt bei.
  • Legen Sie fest EnableMsixTooling , true ob ihr Projekt die MSIX-Pakettools mit einem Projekt verwendet.

Nachdem eine Vorschau mit voll vertrauenswürdiger MSIX-Registrierung und AUMID-Aktivierung verfügbar ist, fügen Sie diese spezifische Version des Microsoft hinzu. Testing.Extensions.PackagedApp-Paket. Verwenden Sie für dieses Setup kein früheres 1.0.0-alpha Paket.

Die MSBuild-Props des Pakets registrieren das Startprogramm über AddSelfRegisteredExtensions. Rufen Sie nicht auch auf AddPackagedAppDeployment. Eine MTP-Ausführung kann nur ein Testhoststartprogramm registrieren.

Das Startprogramm führt die folgenden Aktionen aus:

  1. Es sucht nach einer AppxManifest.xml Datei, die die ausführbare Testdatei beschreibt.
  2. Es registriert das Buildausgabelayout mit Windows.
  3. Es löst die AUMID der App aus dem registrierten Paket und der Manifestanwendungs-ID auf.
  4. Sie aktiviert die App von AUMID und verbindet den aktivierten Prozess mit dem MTP-Controller.

Das Startprogramm ignoriert ein nicht verknüpftes Manifest in einem Vorgängerverzeichnis, es sei denn, ein Application Einstieg verweist auf die ausführbare Datei des Tests. Eine entpackte App, die indirekt auf das Paket verweist, verbleibt im Direct-Start-Pfad.

Erfüllen Sie diese Anforderungen, bevor Sie eine verpackte Test-App ausführen:

  • Verwenden Sie ein Windows spezifisches Zielframework mit Plattformversion 10.0.19041.0 oder höher.
  • Zum Registrieren des nicht signierten Buildausgabelayouts aktivieren Sie den Entwicklermodus, oder konfigurieren Sie querladen.
  • Verwenden Sie eine voll vertrauenswürdige verpackte Desktop-App. Die Erweiterung unterstützt UWP oder andere AppContainer-Hosts nicht.

Caution

Microsoft.Testing.Extensions.PackagedApp und der ITestHostLauncher Erweiterungspunkt sind experimentell. Eine zukünftige Version kann ihre APIs und ihr Verhalten ändern oder entfernen. Bewerten Sie die Risiken, bevor Sie das verpackte Modell in der Produktionstestinfrastruktur verwenden.

Ausführen der Tests

Führen Sie aus dem Verzeichnis, das das WinUI-Testprojekt enthält, Folgendes aus:

dotnet run

Verwenden Sie dotnet run --project .\WinUITests.csprojzum Angeben des Projekts .

Bei einer entpackten App startet MTP die ausführbare Datei direkt. Bei einer verpackten App registriert das App-Startfeld das Layout und aktiviert die App von AUMID.

In beiden Modellen wird das Testfenster geöffnet, MTP führt die Tests aus, und das Fenster wird geschlossen. Das Terminal meldet dann die Testzusammenfassung. Eine erfolgreiche Ausführung wird mit Code 0beendet. Wenn ein Test fehlschlägt, OnLaunched weist das Nonzero-Ergebnis RunAsync zu Environment.ExitCode.

Wird für beide Modelle verwendet dotnet run . Um eine entpackte App direkt auszuführen, verwenden Sie die ausführbare Datei der generierten App. Verwenden Sie nicht dotnet exec , da WinUI PRI-Ressourcen relativ zum Prozesspfad aufgelöst.

Problembehandlung für das Setup

Verwenden Sie die folgenden Überprüfungen auf die am häufigsten auftretenden Setupfehler:

Symptom Prüfen
Die App meldet mehrere Aufrufe an Application.Start. Entfernen Sie das WinUITestTarget Attribut aus der selbst gehosteten Test-App.
Die Testausführung wird abgeschlossen, der Prozess bleibt jedoch geöffnet. Schließen Sie das Testfenster, und rufen Sie Exit nach einem finally Block RunAsyncauf.
Fehlgeschlagene Tests geben trotzdem Prozess-Beendigungscode 0zurück. Zuweisen des Ergebnisses zu RunAsyncEnvironment.ExitCode.
Eine entpackte Ausführung schlägt fehl, da AppxManifest.xml sie fehlt. Vergewissern Sie sich, dass das Projekt MTP aktiviert und dass die Ausführung VSTest nicht verwendet.
Eine verpackte Ausführung kann die App nicht registrieren oder aktivieren. Bestätigen Sie das Windows spezifische Zielframework, den Entwicklermodus oder das Querladen der Konfiguration, das voll vertrauenswürdige App-Modell und den ausführbaren Manifesteintrag.

Siehe auch