Testez les applications WinUI 3 avec MSTest et Microsoft. Testing.Platform

Utilisez Microsoft. Testing.Platform (MTP) pour exécuter des tests MSTest dans une application WinUI 3. L’application WinUI agit en tant qu’hôte de test. Il possède le point d’entrée d’application, le thread d’interface utilisateur et la durée de vie du processus.

Choisissez entre deux modèles de déploiement WinUI 3 :

  • Une application non empaquetée s’exécute en tant qu’exécutable Windows standard.
  • Une application de confiance totale empaquetée conserve l’identité du package MSIX et utilise l’extension expérimentale Microsoft.Testing.Extensions.PackagedApp pour inscrire et activer l’hôte de test.

Important

L’extension empaquetée d’application prend en charge les applications de bureau empaquetées à confiance totale. Il ne prend pas en charge UWP ou d’autres hôtes de test AppContainer.

L’activation AUMID de confiance totale empaquetée est implémentée dans le microsoft/testfx référentiel, mais n’est pas disponible dans un package NuGet public à compter du 6 août 2026. Les packages actuels 1.0.0-alpha ne contiennent pas l'implémentation d'activation spécifique aux Windows. Utilisez la configuration empaquetée uniquement après qu’une version de package identifie la prise en charge de l’inscription MSIX de confiance totale et de l’activation AUMID.

Choisir un modèle de déploiement

Choisissez le modèle de déploiement avant de configurer le projet de test.

Requirement Choisir Démarrage de l’hôte de test
Vos tests n’ont pas besoin d’une identité de package ou d’API qui nécessitent une identité de package. Unpackaged MTP démarre directement l’exécutable de l’application.
Vos tests nécessitent un comportement d’identité de package MSIX ou d’application empaquetée. Confiance totale empaquetée une fois la préversion MTP disponible publiquement L’extension empaquetée d’application inscrit la sortie de build et active l’application par ID de modèle utilisateur d’application (AUMID).
Vos tests doivent s’exécuter dans UWP ou un autre AppContainer. VSTest L’extension package-app MTP ne prend pas en charge l’isolation AppContainer.

Sauf si vos tests nécessitent une identité de package, utilisez une application non empaquetée. Le modèle non empaqueté ne nécessite pas l’inscription de package, le mode développeur ou l’extension d’application empaquetée expérimentale.

Jusqu’à ce qu’une préversion MTP publique inclut l’inscription MSIX de confiance totale et l’activation AUMID, utilisez VSTest pour les tests WinUI 3 de confiance totale empaquetée.

Comprendre la limite UWP

Ne traitez pas UWP comme un autre modèle WinUI 3 empaqueté. Les projets UWP classiques qui ciblent UAP 10 et les projets UWP .NET modernes qui sont définis UseUwp pour true s’exécuter dans un AppContainer. L’empaquetage d’une application de bureau WinUI 3 ne le place pas dans ce modèle d’application.

Utilisez VSTest pour les tests UWP classiques et modernes .NET UWP. Le lanceur d’applications empaquetées MTP cible les hôtes de bureau empaquetés de confiance totale. Il ne peut pas remettre ses arguments d’activation ou sa connexion de contrôleur à un hôte AppContainer.

Pour obtenir une configuration UWP moderne .NET, consultez l’exemple MSTest .NET 9 UWP.

Configurer l’hôte de test WinUI

Les deux modèles de déploiement utilisent la même configuration MTP auto-hébergée.

Définir les propriétés courantes du projet

Définissez ces propriétés dans le projet de test WinUI :

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

Utilisez .NET 8 ou une version ultérieure prise en charge .NET. L’exemple cible Windows version 10.0.19041.0de la plateforme. L’extension empaquetée d’application nécessite cette version ou une version ultérieure.

Conservez l’élément WinUI ApplicationDefinition qui pointe vers le fichier XAML de votre application de test. WinUI génère un point d’entrée à partir de cet élément. Pour empêcher MTP de générer un deuxième point d’entrée, défini GenerateTestingPlatformEntryPoint sur false.

Ajoutez des références de package aux versions compatibles actuelles de MSTest et Microsoft. WindowsAppSDK.

Héberger MTP à partir de l’application

Remplacer OnLaunched dans la classe WinUI Application . Créez et activez la fenêtre de test, puis publiez sa file d’attente de répartiteur :

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

Ajouter using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; pour UITestMethodAttribute.

Créez l’application MTP à partir des arguments de ligne de commande. Inscrivez ensuite les extensions que MSBuild contribue :

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

Ajouter using Microsoft.Testing.Platform.Builder; pour les types de générateur MTP. La build WinUI ajoute EnableMSTestRunner aux arguments de processus. Comme il ne s’agit pas d’une option de ligne de commande MTP, supprimez-la avant de créer l’application de test.

Le projet désactive le point d’entrée MTP généré. Par conséquent, appelez AddSelfRegisteredExtensions. Pour une application empaquetée, la méthode inscrit également le Microsoft.Testing.Extensions.PackagedApp lanceur.

Dans OnLaunched, placez la création et l’exécution de l’application de test dans un try bloc. Affectez le résultat de await app.RunAsync()Environment.ExitCode. Dans un finally bloc, fermez la fenêtre et appelez la méthode de l’application Exit .

Les étapes de cycle de vie offrent deux garanties :

  • Le processus retourne le code de sortie MTP. Par conséquent, un test ayant échoué produit un code de sortie de processus différent de zéro.
  • La boucle de message WinUI s’arrête après l’exécution au lieu de quitter le processus de test actif.

Warning

N’ajoutez [assembly: WinUITestTarget(...)] pas à une application de test WinUI auto-hébergée. L’attribut démarre une application WinUI pour un hôte de test distinct. Une application auto-hébergée appelle Application.Start d’abord. L’attribut tente ensuite de démarrer une deuxième application dans le même processus.

Pour une implémentation complète, consultez l’exemple WinUI non empaqueté et l’exemple WinUI empaqueté.

Exécuter des tests sur le thread d’interface utilisateur

Utilisez UITestMethod pour un test qui crée ou accède à des objets WinUI. MSTest planifie le test sur la file d’attente du répartiteur que vous avez affectée pendant OnLaunched.

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

Un standard TestMethod ne s’exécute pas sur la file d’attente du répartiteur WinUI. Utilisez-le pour les tests qui ne nécessitent pas le thread d’interface utilisateur.

Configurer une application de test non empaquetée

Pour une application non empaquetée, ajoutez ces propriétés :

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

Ne référencez Microsoft.Testing.Extensions.PackagedApppas . L’application non empaquetée n’a pas d’identité MSIX ou AppxManifest.xml dans sa sortie. MTP peut donc démarrer son exécutable directement.

Par défaut, le SDK d'application Windows injecte son initialiseur de démarrage lorsque le projet répond à ces conditions :

  • WindowsPackageType a la valeur None.
  • OutputType est Exe ou WinExe.
  • WindowsAppSDKSelfContained n’est pas true.

Si un hôte qui n'est pas une application SDK d'application Windows charge votre bibliothèque de test, définissez-la WindowsAppSdkBootstrapInitializetrue dans la bibliothèque.

Note

VSTest ne prend pas en charge cette configuration WinUI non empaquetée. Exécutez le projet avec MTP.

Configurer une application de test de confiance totale empaquetée

Conservez la configuration WinUI empaquetée par défaut :

  • Ne définissez pas WindowsPackageType sur None.
  • Conservez et les Package.appxmanifest ressources du package dans le projet.
  • Définissez la valeur EnableMsixToolingtrue si votre projet utilise les outils d’empaquetage MSIX à projet unique.

Après une préversion qui inclut l’inscription MSIX de confiance totale et l’activation AUMID deviennent disponibles, ajoutez cette version spécifique du Microsoft. Package Testing.Extensions.PackageApp. N’utilisez pas de package antérieur 1.0.0-alpha pour cette configuration.

Les propriétés MSBuild du package inscrivent le lanceur via AddSelfRegisteredExtensions. N’appelez AddPackagedAppDeploymentpas non plus . Une exécution MTP ne peut inscrire qu’un seul lanceur d’hôtes de test.

Le lanceur effectue ces actions :

  1. Il recherche un AppxManifest.xml fichier exécutable de test qui décrit l’exécutable de test.
  2. Il inscrit la disposition de sortie de build avec Windows.
  3. Il résout l’AUMID de l’application à partir du package inscrit et de l’ID d’application manifeste.
  4. Il active l’application par AUMID et connecte le processus activé au contrôleur MTP.

Le lanceur ignore un manifeste non lié dans un répertoire ancêtre, sauf si une Application entrée pointe vers l’exécutable de test. Une application non empaquetée qui référence le package reste indirectement sur le chemin de démarrage direct.

Respectez ces exigences avant d’exécuter une application de test empaquetée :

  • Utilisez une infrastructure cible spécifique à Windows avec une version de plateforme ou une version 10.0.19041.0 ultérieure.
  • Pour inscrire la disposition de sortie de build non signée, activez le mode développeur ou configurez le chargement indépendant.
  • Utilisez une application de bureau empaquetée à confiance totale. L’extension ne prend pas en charge UWP ou d’autres hôtes AppContainer.

Avertissement

Microsoft.Testing.Extensions.PackagedApp et le point d’extension ITestHostLauncher sont expérimentaux. Une version ultérieure peut modifier ou supprimer leurs API et leur comportement. Évaluez les risques avant d’utiliser le modèle empaqueté dans l’infrastructure de test de production.

Exécuter les tests

À partir du répertoire qui contient le projet de test WinUI, exécutez :

dotnet run

Pour spécifier le projet, utilisez dotnet run --project .\WinUITests.csproj.

Pour une application non empaquetée, MTP démarre directement l’exécutable. Pour une application empaquetée, le lanceur d’applications empaquetées inscrit la disposition et active l’application par AUMID.

Dans les deux modèles, la fenêtre de test s’ouvre, MTP exécute les tests et la fenêtre se ferme. Le terminal signale ensuite le résumé des tests. Une exécution réussie s’arrête avec du code 0. En cas d’échec d’un test, OnLaunched attribue le résultat différent de zéro RunAsync à Environment.ExitCode.

Utiliser dotnet run pour l’un ou l’autre modèle. Pour exécuter directement une application non empaquetée, utilisez l’exécutable de l’application générée. N’utilisez dotnet exec pas, car WinUI résout les ressources PRI par rapport au chemin du processus.

Résoudre les problèmes d’installation

Utilisez ces vérifications pour les échecs d’installation les plus courants :

Symptôme Vérifier
L’application signale plusieurs appels à Application.Start. Supprimez l’attribut WinUITestTarget de l’application de test auto-hébergée.
L’exécution du test se termine, mais le processus reste ouvert. Fermez la fenêtre de test et appelez-la Exit dans un finally bloc après RunAsync.
Les tests ayant échoué retournent toujours le code 0de sortie du processus. Affectez le résultat de RunAsyncEnvironment.ExitCode.
Une exécution non empaquetée échoue, car AppxManifest.xml elle est manquante. Vérifiez que le projet active MTP et que l’exécution n’utilise pas VSTest.
Une exécution empaquetée ne peut pas inscrire ou activer l’application. Vérifiez l’infrastructure cible spécifique aux Windows, le mode développeur ou la configuration de chargement indépendant, le modèle d’application de confiance totale et l’entrée exécutable du manifeste.

Voir aussi