Testa aplicações WinUI 3 com MSTest e Microsoft. Testing.Platform

Usa a Microsoft. Testing.Platform (MTP) para executar testes MSTest dentro de uma aplicação WinUI 3. A aplicação WinUI atua como anfitrião de teste. Controla o ponto de entrada da aplicação, o thread da interface e a vida útil do processo.

Escolha entre dois modelos de implementação do WinUI 3:

  • Uma aplicação não empacotada corre como um executável normal do Windows.
  • Uma aplicação full-trust empacotada mantém a identidade do pacote MSIX e utiliza a extensão experimental Microsoft.Testing.Extensions.PackagedApp para registar e ativar o host de teste.

Importante

A extensão de aplicação embalada suporta aplicações de desktop empacotadas de confiança total. Não suporta UWP nem outros hosts de teste AppContainer.

A ativação de AUMID full-trust empacotada está implementada no microsoft/testfx repositório, mas não está disponível num pacote público NuGet a partir de 6 de agosto de 2026. Os pacotes atuais 1.0.0-alpha não contêm a implementação de ativação específica do Windows. Use a configuração empacotada apenas depois de um lançamento de pacote identificar suporte para registo total de MSIX e ativação de AUMID.

Escolha um modelo de implementação

Escolha o modelo de implementação antes de configurar o projeto de teste.

Requisito Selecione Arranque do host de teste
Os seus testes não precisam de identidade de pacote nem de APIs que exijam identidade de pacote. Unpackaged O MTP inicia o executável da aplicação diretamente.
Os seus testes requerem identidade de pacote MSIX ou comportamento de aplicação empacotada. Confiança total embalada após a pré-visualização do MTP se tornar pública A extensão da aplicação empacotada regista a saída da compilação e ativa a aplicação pelo ID do Modelo de Utilizador da Aplicação (AUMID).
Os seus testes têm de correr em UWP ou noutro AppContainer. VSTest A extensão de aplicação empacotada MTP não suporta isolamento do AppContainer.

A menos que os teus testes exijam identidade de pacote, usa uma aplicação não embalada. O modelo não empacotado não requer registo de pacotes, Modo Desenvolvedor ou a extensão experimental de aplicação embalada.

Até que uma pré-visualização pública do MTP inclua registo total de confiança de MSIX e ativação de AUMID, utilize o VSTest para testes WinUI 3 de confiança total e empacotados.

Compreenda o limite do UWP

Não trate o UWP como mais um modelo de WinUI 3 embalado. Tanto projetos clássicos UWP que visam UAP 10 como projetos modernos .NET UWP que definem UseUwp para true correr num AppContainer. Empacotar uma aplicação de desktop WinUI 3 não a coloca nesse modelo de aplicação.

Use o VSTest para testes UWP clássicos e .NET modernos. O lançador de aplicações empacotadas MTP tem como alvo hosts de desktop empacotados de confiança total. Não consegue entregar os seus argumentos de ativação nem a ligação ao controlador para um host AppContainer.

Para uma configuração .NET UWP moderna, veja o exemplo MSTest .NET 9 UWP.

Configurar o host de teste do WinUI

Ambos os modelos de implementação utilizam a mesma configuração MTP auto-hospedada.

Definir as propriedades comuns do projeto

Defina estas propriedades no projeto de teste WinUI:

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

Use o .NET 8 ou uma versão .NET suportada posteriormente. O exemplo dirige-se à versão 10.0.19041.0da plataforma Windows . A extensão da aplicação empacotada requer esta versão ou posterior.

Mantém o item do WinUI ApplicationDefinition que aponta para o ficheiro XAML da tua aplicação de teste. O WinUI gera um ponto de entrada a partir desse item. Para evitar que o MTP gere um segundo ponto de entrada, defina GenerateTestingPlatformEntryPoint para false.

Adicionar referências de pacotes às versões compatíveis atuais do MSTest e da Microsoft. WindowsAppSDK.

Host MTP a partir da aplicação

Override OnLaunched na classe WinUI Application . Crie e ative a janela de teste e depois publique a fila do despachante:

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

Adicionar using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; para UITestMethodAttribute.

Crie a aplicação MTP a partir dos argumentos da linha de comandos. Depois, regista as extensões que o MSBuild contribui:

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

Adicionar using Microsoft.Testing.Platform.Builder; para os tipos de construtores MTP. A build do WinUI contribui EnableMSTestRunner para os argumentos do processo. Como não é uma opção de linha de comandos MTP, remova-a antes de criar a aplicação de teste.

O projeto desativa o ponto de entrada MTP gerado, por isso chama AddSelfRegisteredExtensions. Para uma aplicação empacotada, o método também regista o Microsoft.Testing.Extensions.PackagedApp lançador.

Em OnLaunched, coloque a criação e execução de aplicações de teste num try bloco. Atribua o resultado de await app.RunAsync() a Environment.ExitCode. Num finally bloco, fecha a janela e chama o método da Exit aplicação.

As etapas do ciclo de vida oferecem duas garantias:

  • O processo devolve o código de saída MTP, pelo que um teste falhado produz um código de saída de processo não nulo.
  • O ciclo de mensagens WinUI para após a execução em vez de deixar o processo de teste ativo.

Warning

Não adiciones [assembly: WinUITestTarget(...)] a uma aplicação de teste WinUI auto-hospedada. O atributo inicia uma aplicação WinUI para um host de teste separado. Uma aplicação self-hosted liga Application.Start primeiro. O atributo tenta então iniciar uma segunda aplicação no mesmo processo.

Para uma implementação completa, veja o exemplo não empacotado do WinUI e o exemplo do WinUI empacotado.

Executa testes no tópico da interface de utilizador

Use UITestMethod para um teste que crie ou aceda a objetos WinUI. O MSTest agenda o teste na fila do despachante que atribuiu durante OnLaunched.

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

Um regular TestMethod não corre na fila do despachante do WinUI. Usa-o para testes que não requerem o tópico da interface.

Configurar uma aplicação de teste não embalada

Para uma aplicação não embalada, adicione estas propriedades:

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

Não faça referência Microsoft.Testing.Extensions.PackagedAppa . A aplicação não empacotada não tem identidade MSIX nem AppxManifest.xml na sua saída, pelo que o MTP pode iniciar o seu executável diretamente.

Por defeito, o SDK de Aplicações Windows injeta o seu inicializador de bootstrap quando o projeto cumpre estas condições:

  • WindowsPackageType é None.
  • OutputType é Exe ou WinExe.
  • WindowsAppSDKSelfContained não trueé.

Se um host que não é uma aplicação do SDK de Aplicações Windows carregar a tua biblioteca de teste, define WindowsAppSdkBootstrapInitialize para true dentro da biblioteca.

Note

O VSTest não suporta esta configuração WinUI não empacotada. Gere o projeto com o MTP.

Configure uma aplicação de teste full-trust empacotada

Mantém a configuração predefinida do WinUI:

  • Não definas WindowsPackageType para None.
  • Mantém Package.appxmanifest e os assets do pacote no projeto.
  • Defina EnableMsixTooling para true se o seu projeto usar as ferramentas de empacotamento MSIX de projeto único.

Depois de uma pré-visualização que inclui registo total de MSIX e ativação de AUMID ficar disponível, adicione essa versão específica da Microsoft. Pacote Testing.Extensions.PackagedApp. Não uses um pacote anterior 1.0.0-alpha para esta configuração.

Os props MSBuild do pacote registam o lançador através de AddSelfRegisteredExtensions. Também não ligues AddPackagedAppDeployment. Uma execução MTP só pode registar um lançador de host de teste.

O lançador executa as seguintes ações:

  1. Verifica se descreve AppxManifest.xml o executável de teste.
  2. Regista o layout build-output com o Windows.
  3. Resolve o AUMID da aplicação a partir do pacote registado e do ID da aplicação do manifesto.
  4. Ativa a aplicação através de AUMID e liga o processo ativado ao controlador MTP.

O lançador ignora um manifesto não relacionado num diretório ancestral, a menos que uma Application entrada aponte para o executável de teste. Uma aplicação não empacotada que faz referência ao pacote indiretamente mantém-se no caminho de início direto.

Cumpra estes requisitos antes de executar uma aplicação de teste embalada:

  • Use uma framework de destino específica do Windows com versão 10.0.19041.0 da plataforma ou posterior.
  • Para registar o layout de build-output sem assinatura, ative o Modo Desenvolvedor ou configure o sideloading.
  • Use uma aplicação de desktop empacotada com total confiança. A extensão não suporta UWP nem outros hosts AppContainer.

Caution

Microsoft.Testing.Extensions.PackagedApp e o ITestHostLauncher ponto de extensão são experimentais. Uma versão futura pode alterar ou remover as suas APIs e comportamentos. Avalie os riscos antes de usar o modelo empacotado na infraestrutura de teste de produção.

Executar os testes

A partir do diretório que contém o projeto de teste WinUI, execute:

dotnet run

Para especificar o projeto, use dotnet run --project .\WinUITests.csproj.

Para uma aplicação não empacotada, o MTP inicia o executável diretamente. Para uma aplicação empacotada, o lançador de aplicações empacotadas regista o layout e ativa a aplicação pelo AUMID.

Em ambos os modelos, a janela de teste abre-se, o MTP executa os testes e a janela fecha-se. O terminal depois reporta o resumo do teste. Uma execução bem-sucedida sai com código 0. Quando um teste falha, OnLaunched atribui o resultado não nulo RunAsync a Environment.ExitCode.

Use dotnet run para qualquer um dos modelos. Para executar uma aplicação não embalada diretamente, use o executável gerado pela app. Não uses dotnet exec porque o WinUI resolve recursos PRI em relação ao caminho do processo.

Resolver o problema da configuração

Use estas verificações para as falhas de configuração mais comuns:

Symptom Verificar
A aplicação reporta múltiplas chamadas para Application.Start. Remova o WinUITestTarget atributo da aplicação de teste auto-hospedada.
O teste termina, mas o processo mantém-se aberto. Fecha a janela de teste e liga Exit um finally bloco depois RunAsyncde .
Testes falhados continuam a devolver código 0de saída do processo. Atribua o resultado de RunAsync a Environment.ExitCode.
Uma execução não empacotada falha porque AppxManifest.xml está em falta. Confirma que o projeto ativa o MTP e que a execução não usa VSTest.
Uma corrida embalada não consegue registar nem ativar a aplicação. Confirme o framework alvo específico do Windows, o Modo Desenvolvedor ou configuração de sideloading, o modelo de aplicação de confiança total e a entrada do executável do manifesto.

Consulte também