A Microsoft apresentou um guia prático para testar aplicações UWP e WinUI 3 por meio do MSTest e do Microsoft.Testing.Platform, unificando o ciclo de vida dos testes entre diferentes modelos de execução, incluindo aplicações empacotadas no formato MSIX, aplicações não empacotadas e aplicações executadas dentro do AppContainer. O material foi escrito por Amaury Levé, engenheiro de software principal, e concentra-se nos detalhes que determinam como o host de teste é executado, mais do que na escrita dos próprios testes de interface.
Escolha do modelo de execução
A Microsoft diferencia o empacotamento do nível de confiança. O empacotamento adiciona uma identidade MSIX e um meio de ativação AUMID, enquanto o nível de confiança determina se o processo é executado com privilégios completos ou dentro do AppContainer. O material recomenda começar com uma aplicação WinUI 3 não empacotada quando não forem necessárias a identidade do pacote, os contratos de ativação empacotados ou a reprodução do comportamento da aplicação instalada. Já a UWP permanece, por natureza, vinculada ao empacotamento e ao ambiente AppContainer.
Nas aplicações não empacotadas, o Microsoft.Testing.Platform usa um caminho de execução direto a partir do apphost, enquanto as aplicações empacotadas precisam do registro do layout do pacote e da ativação por meio do AUMID. As aplicações WinUI 3 configuradas para funcionar dentro do AppContainer também precisam de uma delegação precisa de acesso aos canais de comunicação do console, ao cancelamento, aos arquivos TRX, ao HangDump e à nova tentativa; a Microsoft alerta contra a concessão da permissão ALL APPLICATION PACKAGES em vez disso.
Configuração do MSTest e do Microsoft.Testing.Platform
A Microsoft recomenda instalar a versão MSTest.Sdk 4.5 e selecionar o Microsoft.Testing.Platform no arquivo global.json, para que o comando dotnet test use a plataforma de testes nativa do .NET 10 em vez do VSTest. O MSTest.Sdk 4.5 inclui a plataforma MTP 2.5, o módulo de console secundário específico dos modelos de aplicações, os recursos necessários para UWP e um executor de aplicações empacotadas.
Na UWP moderna, a configuração exige o uso de UseUwp e PublishAot com uma estrutura de destino adequada do Windows. A aplicação deve passar os argumentos de ativação ao auxiliar gerado MicrosoftTestingPlatformApplication.RunAsync a partir de OnLaunched, usando PackagedAppExtensions.GetTestApplicationArguments. Já os projetos UWP tradicionais mantêm sua estrutura atual e importam o MSTest.Sdk juntamente com o MSBuild.Sdk.Extras, executando os testes a partir do Developer PowerShell por meio do destino InvokeTestingPlatform.
Host WinUI 3 e dispatcher da interface
O material propõe a criação de uma aplicação de teste WinUI 3 hospedada por si própria, na qual a aplicação cria sua janela, possui o ponto de entrada e executa o MSTest dentro do mesmo processo. Depois de ativar a janela, a aplicação publica um objeto DispatcherQueue em UITestMethodAttribute.DispatcherQueue e então chama RunAsync. Environment.ExitCode deve ser definido como o resultado da execução dos testes, porque o ponto de entrada criado pelo WinUI retorna void, e ignorar isso pode fazer com que uma execução com falha apareça como bem-sucedida para o sistema de compilação ou CI.
O exemplo esclarece que UITestMethod encaminha o teste completo, incluindo TestInitialize e TestCleanup, ao dispatcher do WinUI. Já STATestMethod fornece uma thread STA, mas não cria por si só um dispatcher do WinUI e, portanto, não é suficiente para testes de interface que dependem do DispatcherQueue.
O que muda na prática?
O principal valor dessa abordagem é a possibilidade de manter o MSTest e o mesmo ciclo de vida dos testes ao passar entre UWP e WinUI 3 ou entre a execução empacotada e não empacotada, alterando apenas as configurações de publicação e o caminho de inicialização. No WinUI 3 não empacotado, WindowsPackageType é definido como None e as ferramentas de MSIX são desativadas. Já a execução empacotada mantém o manifesto Package.appxmanifest e os recursos do pacote, exigindo um TFM do Windows igual ou posterior a 10.0.19041.0 e uma política que permita a instalação lateral, como o Developer Mode.
Os dois modelos podem ser executados por meio de dotnet run ou dotnet test --project no .NET 10, enquanto os testes UWP e WinUI 3 dentro do AppContainer são executados por meio do destino MSBuild personalizado e a partir do Developer PowerShell sem privilégios elevados. A Microsoft alerta contra o uso de dotnet exec com a aplicação não empacotada, pois inserir dotnet.exe no caminho de execução pode causar problemas no carregamento dos recursos do WinUI.
Validação no CI
O sucesso da compilação não é suficiente para confirmar a validade dos testes empacotados. É necessário verificar a imagem real do agente de CI, o contexto do usuário que registra o pacote, a política do Developer Mode ou da instalação lateral e as estruturas declaradas pelo pacote. Um computador de desenvolvedor no qual o Windows App SDK ou os pacotes UWP já estejam instalados pode ocultar uma lacuna que só aparecerá em um agente limpo. Além disso, as aplicações dependentes de uma estrutura do Windows App SDK precisam da versão correspondente do runtime, a menos que sejam compiladas no formato self-contained; mesmo nesse caso, o próprio modelo de pacote que será usado no CI deve ser testado.