diff --git a/docs/core/testing/microsoft-testing-platform-intro.md b/docs/core/testing/microsoft-testing-platform-intro.md index a24362cdd5560..8f723de2fd7b2 100644 --- a/docs/core/testing/microsoft-testing-platform-intro.md +++ b/docs/core/testing/microsoft-testing-platform-intro.md @@ -3,7 +3,8 @@ title: Microsoft.Testing.Platform overview - .NET test runner description: Learn about Microsoft.Testing.Platform (MTP), a lightweight and portable .NET test runner and VSTest alternative for running unit tests in CI pipelines, CLI, and IDEs. author: Evangelink ms.author: amauryleve -ms.date: 03/17/2024 +ms.date: 08/06/2026 +ai-usage: ai-assisted --- # Microsoft.Testing.Platform (MTP) overview @@ -25,6 +26,7 @@ Use the following path, based on what you need next: - Understand platform behavior in CLI: [Testing with `dotnet test`](./unit-testing-with-dotnet-test.md) - Find platform and extension CLI switches in one place: [MTP CLI options reference](./microsoft-testing-platform-cli-options.md) - Configure framework runners: [Run tests with MSTest](./unit-testing-mstest-running-tests.md) or [MTP support in NUnit (NUnit runner)](./unit-testing-nunit-runner-intro.md) +- Host MTP in a WinUI 3 app: [Test WinUI 3 apps with MSTest and MTP](./unit-testing-mstest-winui.md) - Migrate an existing VSTest setup: [Migrate from VSTest to MTP](./migrating-vstest-microsoft-testing-platform.md) - Add diagnostics, coverage, and reporting: [MTP features](./microsoft-testing-platform-features.md) - Build your own extension: [MTP architecture](./microsoft-testing-platform-architecture.md), [Extension points](./microsoft-testing-platform-architecture-extensions.md), and [Services](./microsoft-testing-platform-architecture-services.md) diff --git a/docs/core/testing/microsoft-testing-platform-test-host-deployment.md b/docs/core/testing/microsoft-testing-platform-test-host-deployment.md index 1413e06fe0a27..d9aaa1c4160ad 100644 --- a/docs/core/testing/microsoft-testing-platform-test-host-deployment.md +++ b/docs/core/testing/microsoft-testing-platform-test-host-deployment.md @@ -1,25 +1,33 @@ --- title: Microsoft.Testing.Platform (MTP) test host deployment -description: Learn about the MTP extensions that control how and where the test host is deployed and launched. +description: Learn how MTP extensions control test host deployment and startup. author: evangelink ms.author: amauryleve -ms.date: 07/09/2026 +ms.date: 08/06/2026 ai-usage: ai-assisted --- # Test host deployment -These extensions control how and where the test host is deployed and launched. They build on the experimental `ITestHostLauncher` extension point, which lets an extension take over the deployment and launch of the test host instead of starting it in place. Each extension requires an additional NuGet package, as described in each section. +These extensions control how and where MTP deploys and starts the test host. They use the experimental `ITestHostLauncher` extension point to control test host deployment and startup. Each extension requires another NuGet package, as described in each section. > [!TIP] -> When using [Microsoft.Testing.Platform.MSBuild](https://www.nuget.org/packages/Microsoft.Testing.Platform.MSBuild) (included transitively by MSTest, NUnit, and xUnit runners), these extensions are auto-registered when you install their NuGet packages — no code changes needed. The manual registration specified in this article is only required if you disabled the auto-generated entry point by setting `false`. +> When you use [Microsoft.Testing.Platform.MSBuild](https://www.nuget.org/packages/Microsoft.Testing.Platform.MSBuild), install an extension's NuGet package to register the extension automatically. MSTest, NUnit, and xUnit runners include `Microsoft.Testing.Platform.MSBuild` transitively. If you disable the generated entry point, call `AddSelfRegisteredExtensions` to register the packages that MSBuild contributes. ## Packaged app deployment -The packaged app deployment extension deploys a packaged Windows test host (UWP or packaged WinUI) into an isolated directory and launches it from there, rather than starting the test host in place. It's the reference consumer of the experimental `ITestHostLauncher` extension point for packaged Windows apps. This extension requires the [Microsoft.Testing.Extensions.PackagedApp](https://nuget.org/packages/Microsoft.Testing.Extensions.PackagedApp) NuGet package. +The packaged-app extension registers a full-trust packaged Windows test host from its build-output layout and activates it by Application User Model ID (AUMID). It's the reference consumer of the experimental `ITestHostLauncher` extension point for packaged Windows apps. This extension requires the [Microsoft.Testing.Extensions.PackagedApp](https://nuget.org/packages/Microsoft.Testing.Extensions.PackagedApp) NuGet package. > [!NOTE] -> Available in MTP starting with version 2.3.0. This extension is experimental, and its options and output format might change in a future version. +> The extension package is available starting with MTP version 2.3.0. Full-trust MSIX registration and AUMID activation are implemented in the `microsoft/testfx` repository but aren't available in a public NuGet package as of August 6, 2026. The extension is experimental, and its options and output format might change in a future version. + +Meet these requirements before you use the extension: + +- Target Windows platform version `10.0.19041.0` or later. +- To register an unsigned build-output layout, enable Developer Mode or configure sideloading. +- Use a full-trust packaged desktop host. The extension doesn't support classic UWP, modern .NET UWP with `UseUwp`, or other AppContainer hosts. + +For a complete self-hosted WinUI configuration, see [Test WinUI 3 apps with MSTest and MTP](unit-testing-mstest-winui.md). ### Manual registration @@ -27,3 +35,5 @@ The packaged app deployment extension deploys a packaged Windows test host (UWP var builder = await TestApplication.CreateBuilderAsync(args); builder.AddPackagedAppDeployment(); ``` + +Don't call `AddPackagedAppDeployment` if a self-hosted application already calls `AddSelfRegisteredExtensions` and references the package. An MTP run can register only one test host launcher. diff --git a/docs/core/testing/test-platforms-overview.md b/docs/core/testing/test-platforms-overview.md index 1b0d004dd72af..cb2e95f4ed0b4 100644 --- a/docs/core/testing/test-platforms-overview.md +++ b/docs/core/testing/test-platforms-overview.md @@ -3,7 +3,7 @@ title: Microsoft.Testing.Platform vs VSTest - .NET test platform comparison description: Compare Microsoft.Testing.Platform (MTP) and VSTest to choose the right .NET test platform for your projects, CI pipelines, and IDE integration. author: Evangelink ms.author: amauryleve -ms.date: 02/24/2026 +ms.date: 08/06/2026 ai-usage: ai-assisted --- @@ -29,7 +29,9 @@ Use the following scenarios to choose quickly. | Use case | Choose | Why | |---|---|---| | You need Native AOT or trimming test execution scenarios. | MTP | MTP supports these modern deployment scenarios, while VSTest doesn't. | -| You're building packaged WinUI or UWP test projects. | VSTest | These project types aren't currently supported by MTP. | +| You're testing classic UWP, modern .NET UWP with `UseUwp`, or another AppContainer project. | VSTest | The MTP packaged-app extension supports full-trust packaged desktop hosts, not AppContainer hosts. | +| You're testing an unpackaged WinUI 3 app. | MTP | MTP can run inside the WinUI app and start its executable directly. | +| You're testing a packaged full-trust WinUI 3 app. | VSTest | Use VSTest until the experimental MTP extension for package registration and AUMID activation becomes available in a public NuGet package. | | You need to mix .NET tests and non-.NET test adapters (for example JavaScript or C++ adapters). | VSTest | VSTest supports mixed-language adapter scenarios, while MTP is .NET-specific. | | You want test projects to behave like regular executables (`dotnet run`, direct executable run, `dotnet watch`, and startup-project F5 flows). | MTP | MTP is executable-first, so test apps run like standard .NET apps in local and CI workflows. | | You rely on long-established integrations across existing tooling. | VSTest | VSTest has the longest compatibility track record across existing products, tasks, and pipelines. MTP support is growing in the ecosystem, but some integrations may lag behind VSTest. | @@ -71,3 +73,4 @@ For complete details about `dotnet test` modes and arguments, see [Testing with - Understand VSTest options: [VSTest options](/visualstudio/test/vstest-console-options) - Migrate from VSTest: [Migrate from VSTest to MTP](./migrating-vstest-microsoft-testing-platform.md) - Add capabilities: [MTP features](./microsoft-testing-platform-features.md) +- Test WinUI 3 apps: [Test WinUI 3 apps with MSTest and MTP](./unit-testing-mstest-winui.md) diff --git a/docs/core/testing/unit-testing-mstest-intro.md b/docs/core/testing/unit-testing-mstest-intro.md index a76a53c0665b7..2e1c986b51c52 100644 --- a/docs/core/testing/unit-testing-mstest-intro.md +++ b/docs/core/testing/unit-testing-mstest-intro.md @@ -3,7 +3,8 @@ title: MSTest overview description: Learn about MSTest, Microsoft's testing framework for .NET, including supported platforms, key features, and getting started. author: Evangelink ms.author: amauryleve -ms.date: 07/15/2025 +ms.date: 08/06/2026 +ai-usage: ai-assisted --- # MSTest overview @@ -31,8 +32,8 @@ MSTest supports a wide range of .NET platforms and target frameworks. The follow |----------|-------------------|-------------------|-------------------|-------| | **.NET** | .NET 8+ | Full parallelization | All attributes | Recommended for new projects | | **.NET Framework** | 4.6.2+ | Full parallelization | All attributes | Full feature support | -| **UWP** | UAP 10, .NET 9+ with UAP | UI thread | `UITestMethod` | Requires settings `true`; see [UWP sample](https://github.com/microsoft/testfx/tree/main/samples/public/BlankUwpNet9App) | -| **WinUI 3** | .NET 8+ | UI thread | `UITestMethod` | Requires Windows App SDK; see [WinUI sample](https://github.com/microsoft/testfx/tree/main/samples/public/BlankWinUINet9App) | +| **UWP** | UAP 10, .NET 9+ with UAP | UI thread | `UITestMethod` | Use VSTest. Modern .NET UWP requires `true`; see [UWP sample](https://github.com/microsoft/testfx/tree/main/samples/public/BlankUwpNet9App) | +| **WinUI 3** | .NET 8+ | UI thread | `UITestMethod` | Requires Windows App SDK; see [Test WinUI 3 apps with MSTest and MTP](unit-testing-mstest-winui.md) | | **Native AOT** | .NET 8+ | Full parallelization | Most attributes | Limited feature set; see [Native AOT sample](https://github.com/microsoft/testfx/tree/main/samples/public/mstest-runner/NativeAotRunner) | ### Platform-specific considerations @@ -55,7 +56,7 @@ public class UwpTests } ``` -For UWP setup, see the [BlankUwpNet9App sample](https://github.com/microsoft/testfx/tree/main/samples/public/BlankUwpNet9App). +Use VSTest for classic UWP and modern .NET UWP because both run in an AppContainer. For a modern .NET UWP setup, see the [BlankUwpNet9App sample](https://github.com/microsoft/testfx/tree/main/samples/public/BlankUwpNet9App). #### WinUI 3 testing @@ -75,7 +76,7 @@ public class WinUITests } ``` -For WinUI setup, see the [BlankWinUINet9App sample](https://github.com/microsoft/testfx/tree/main/samples/public/BlankWinUINet9App) and [MSTestRunnerWinUI sample](https://github.com/microsoft/testfx/tree/main/samples/public/mstest-runner/MSTestRunnerWinUI). +To configure unpackaged or packaged full-trust WinUI 3 tests, see [Test WinUI 3 apps with MSTest and MTP](unit-testing-mstest-winui.md). #### Native AOT @@ -125,5 +126,6 @@ The MSTest team carefully reviews and minimizes breaking changes. When breaking - [Get started with MSTest](unit-testing-mstest-getting-started.md) - [Write tests](unit-testing-mstest-writing-tests.md) - [Run tests](unit-testing-mstest-running-tests.md) +- [Test WinUI 3 apps](unit-testing-mstest-winui.md) - [Configure MSTest](unit-testing-mstest-configure.md) - [MSTest code analyzers](mstest-analyzers/overview.md) diff --git a/docs/core/testing/unit-testing-mstest-running-tests.md b/docs/core/testing/unit-testing-mstest-running-tests.md index 612d3be782bcf..2b80490daef1b 100644 --- a/docs/core/testing/unit-testing-mstest-running-tests.md +++ b/docs/core/testing/unit-testing-mstest-running-tests.md @@ -3,7 +3,8 @@ title: Run tests with MSTest description: Learn about how to run MSTest tests using VSTest or Microsoft.Testing.Platform (MTP). author: Evangelink ms.author: amauryleve -ms.date: 07/24/2024 +ms.date: 08/06/2026 +ai-usage: ai-assisted --- # Run tests with MSTest @@ -151,5 +152,6 @@ Contoso.MyTests.exe --filter "FullyQualifiedName~UnitTest1|TestCategory=Category ## See also - [Testing with `dotnet test`](unit-testing-with-dotnet-test.md) +- [Test WinUI 3 apps with MSTest and MTP](unit-testing-mstest-winui.md) - [Filter tests](selective-unit-tests.md) - [Order unit tests](order-unit-tests.md) diff --git a/docs/core/testing/unit-testing-mstest-winui.md b/docs/core/testing/unit-testing-mstest-winui.md new file mode 100644 index 0000000000000..f64dc0dd8cdf2 --- /dev/null +++ b/docs/core/testing/unit-testing-mstest-winui.md @@ -0,0 +1,206 @@ +--- +title: Test WinUI 3 apps with MSTest and Microsoft.Testing.Platform +description: Learn how to configure unpackaged and packaged full-trust WinUI 3 test apps with MSTest and Microsoft.Testing.Platform. +author: Evangelink +ms.author: amauryleve +ms.date: 08/06/2026 +ai-usage: ai-assisted +--- + +# Test WinUI 3 apps with MSTest and Microsoft.Testing.Platform + +Use Microsoft.Testing.Platform (MTP) to run MSTest tests inside a WinUI 3 app. The WinUI app acts as the test host. It owns the application entry point, UI thread, and process lifetime. + +Choose between two WinUI 3 deployment models: + +- An **unpackaged app** runs as a regular Windows executable. +- A **packaged full-trust app** keeps MSIX package identity and uses the experimental `Microsoft.Testing.Extensions.PackagedApp` extension to register and activate the test host. + +> [!IMPORTANT] +> The packaged-app extension supports full-trust packaged desktop apps. It doesn't support UWP or other AppContainer test hosts. +> +> Packaged full-trust AUMID activation is implemented in the `microsoft/testfx` repository but isn't available in a public NuGet package as of August 6, 2026. The current `1.0.0-alpha` packages don't contain the Windows-specific activation implementation. Use the packaged setup only after a package release identifies support for full-trust MSIX registration and AUMID activation. + +## Choose a deployment model + +Choose the deployment model before you configure the test project. + +| Requirement | Choose | Test host startup | +|---|---|---| +| Your tests don't need package identity or APIs that require package identity. | Unpackaged | MTP starts the app executable directly. | +| Your tests require MSIX package identity or packaged-app behavior. | Packaged full-trust after the MTP preview becomes publicly available | The packaged-app extension registers the build output and activates the app by Application User Model ID (AUMID). | +| Your tests must run in UWP or another AppContainer. | VSTest | The MTP packaged-app extension doesn't support AppContainer isolation. | + +Unless your tests require package identity, use an unpackaged app. The unpackaged model doesn't require package registration, Developer Mode, or the experimental packaged-app extension. + +Until a public MTP preview includes full-trust MSIX registration and AUMID activation, use VSTest for packaged full-trust WinUI 3 tests. + +### Understand the UWP boundary + +Don't treat UWP as another packaged WinUI 3 model. Both classic UWP projects that target UAP 10 and modern .NET UWP projects that set `UseUwp` to `true` run in an AppContainer. Packaging a WinUI 3 desktop app doesn't place it in that app model. + +Use VSTest for classic UWP and modern .NET UWP tests. The MTP packaged-app launcher targets full-trust packaged desktop hosts. It can't deliver its activation arguments or controller connection to an AppContainer host. + +For a modern .NET UWP configuration, see the [MSTest .NET 9 UWP sample](https://github.com/microsoft/testfx/tree/main/samples/public/BlankUwpNet9App). + +## Configure the WinUI test host + +Both deployment models use the same self-hosted MTP setup. + +### Set the common project properties + +Set these properties in the WinUI test project: + +```xml +Exe +net8.0-windows10.0.19041.0 +true +true +false +``` + +Use .NET 8 or a later supported .NET version. The example targets Windows platform version `10.0.19041.0`. The packaged-app extension requires this version or later. + +Keep the WinUI `ApplicationDefinition` item that points to your test app's XAML file. WinUI generates an entry point from that item. To prevent MTP from generating a second entry point, set `GenerateTestingPlatformEntryPoint` to `false`. + +Add package references to the current compatible versions of [MSTest](https://www.nuget.org/packages/MSTest) and [Microsoft.WindowsAppSDK](https://www.nuget.org/packages/Microsoft.WindowsAppSDK). + +### Host MTP from the application + +Override `OnLaunched` in the WinUI `Application` class. Create and activate the test window, and then publish its dispatcher queue: + +```csharp +_window = new UnitTestAppWindow(); +_window.Activate(); +UITestMethodAttribute.DispatcherQueue = _window.DispatcherQueue; +``` + +Add `using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;` for `UITestMethodAttribute`. + +Create the MTP application from the command-line arguments. Then register the extensions that MSBuild contributes: + +```csharp +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(); +``` + +Add `using Microsoft.Testing.Platform.Builder;` for the MTP builder types. The WinUI build adds `EnableMSTestRunner` to the process arguments. Because it isn't an MTP command-line option, remove it before you create the test application. + +The project disables the generated MTP entry point, so call `AddSelfRegisteredExtensions`. For a packaged app, the method also registers the `Microsoft.Testing.Extensions.PackagedApp` launcher. + +In `OnLaunched`, put test application creation and execution in a `try` block. Assign the result of `await app.RunAsync()` to `Environment.ExitCode`. In a `finally` block, close the window and call the application's `Exit` method. + +The lifecycle steps provide two guarantees: + +- The process returns the MTP exit code, so a failed test produces a nonzero process exit code. +- The WinUI message loop stops after the run instead of leaving the test process active. + +> [!WARNING] +> Don't add `[assembly: WinUITestTarget(...)]` to a self-hosted WinUI test app. The attribute starts a WinUI application for a separate test host. A self-hosted app calls `Application.Start` first. The attribute then tries to start a second application in the same process. + +For a complete implementation, see the [unpackaged WinUI sample](https://github.com/microsoft/testfx/tree/main/samples/public/mstest-runner/MSTestRunnerWinUIUnpackaged) and the [packaged WinUI sample](https://github.com/microsoft/testfx/tree/main/samples/public/mstest-runner/MSTestRunnerWinUI). + +### Run tests on the UI thread + +Use `UITestMethod` for a test that creates or accesses WinUI objects. MSTest schedules the test on the dispatcher queue that you assigned during `OnLaunched`. + +```csharp +[UITestMethod] +public void CreatesControlOnUiThread() +{ + var grid = new Grid(); + Assert.IsTrue(grid.DispatcherQueue.HasThreadAccess); +} +``` + +A regular `TestMethod` doesn't run on the WinUI dispatcher queue. Use it for tests that don't require the UI thread. + +## Configure an unpackaged test app + +For an unpackaged app, add these properties: + +```xml +None +false +``` + +Don't reference `Microsoft.Testing.Extensions.PackagedApp`. The unpackaged app has no MSIX identity or `AppxManifest.xml` in its output, so MTP can start its executable directly. + +By default, the Windows App SDK injects its bootstrap initializer when the project meets these conditions: + +- `WindowsPackageType` is `None`. +- `OutputType` is `Exe` or `WinExe`. +- `WindowsAppSDKSelfContained` isn't `true`. + +If a host that isn't a Windows App SDK app loads your test library, set `WindowsAppSdkBootstrapInitialize` to `true` in the library. + +> [!NOTE] +> VSTest doesn't support this unpackaged WinUI configuration. Run the project with MTP. + +## Configure a packaged full-trust test app + +Keep the default packaged WinUI configuration: + +- Don't set `WindowsPackageType` to `None`. +- Keep `Package.appxmanifest` and the package assets in the project. +- Set `EnableMsixTooling` to `true` if your project uses the single-project MSIX packaging tools. + +After a preview that includes full-trust MSIX registration and AUMID activation becomes available, add that specific version of the [Microsoft.Testing.Extensions.PackagedApp](https://www.nuget.org/packages/Microsoft.Testing.Extensions.PackagedApp) package. Don't use an earlier `1.0.0-alpha` package for this setup. + +The package's MSBuild props register the launcher through `AddSelfRegisteredExtensions`. Don't also call `AddPackagedAppDeployment`. An MTP run can register only one test host launcher. + +The launcher performs these actions: + +1. It checks for an `AppxManifest.xml` that describes the test executable. +1. It registers the build-output layout with Windows. +1. It resolves the app's AUMID from the registered package and manifest application ID. +1. It activates the app by AUMID and connects the activated process to the MTP controller. + +The launcher ignores an unrelated manifest in an ancestor directory unless an `Application` entry points to the test executable. An unpackaged app that references the package indirectly remains on the direct-start path. + +Meet these requirements before you run a packaged test app: + +- Use a Windows-specific target framework with platform version `10.0.19041.0` or later. +- To register the unsigned build-output layout, enable Developer Mode or configure sideloading. +- Use a full-trust packaged desktop app. The extension doesn't support UWP or other AppContainer hosts. + +> [!CAUTION] +> `Microsoft.Testing.Extensions.PackagedApp` and the `ITestHostLauncher` extension point are experimental. A future release might change or remove their APIs and behavior. Evaluate the risks before you use the packaged model in production test infrastructure. + +## Run the tests + +From the directory that contains the WinUI test project, run: + +```dotnetcli +dotnet run +``` + +To specify the project, use `dotnet run --project .\WinUITests.csproj`. + +For an unpackaged app, MTP starts the executable directly. For a packaged app, the packaged-app launcher registers the layout and activates the app by AUMID. + +In both models, the test window opens, MTP runs the tests, and the window closes. The terminal then reports the test summary. A successful run exits with code `0`. When a test fails, `OnLaunched` assigns the nonzero `RunAsync` result to `Environment.ExitCode`. + +Use `dotnet run` for either model. To run an unpackaged app directly, use the generated app executable. Don't use `dotnet exec` because WinUI resolves PRI resources relative to the process path. + +## Troubleshoot the setup + +Use these checks for the most common setup failures: + +| Symptom | Check | +|---|---| +| The app reports multiple calls to `Application.Start`. | Remove the `WinUITestTarget` attribute from the self-hosted test app. | +| The test run finishes but the process stays open. | Close the test window and call `Exit` in a `finally` block after `RunAsync`. | +| Failed tests still return process exit code `0`. | Assign the result of `RunAsync` to `Environment.ExitCode`. | +| An unpackaged run fails because `AppxManifest.xml` is missing. | Confirm that the project enables MTP and that the run doesn't use VSTest. | +| A packaged run can't register or activate the app. | Confirm the Windows-specific target framework, Developer Mode or sideloading configuration, full-trust app model, and manifest executable entry. | + +## See also + +- [MSTest overview](unit-testing-mstest-intro.md) +- [Run tests with MSTest](unit-testing-mstest-running-tests.md) +- [MTP test host deployment](microsoft-testing-platform-test-host-deployment.md) +- [WinUI testing guidance in the MSTest repository](https://github.com/microsoft/testfx/blob/main/docs/winui-testing.md) diff --git a/docs/navigate/devops-testing/toc.yml b/docs/navigate/devops-testing/toc.yml index 6da6c8c909e45..275d64c39dab8 100644 --- a/docs/navigate/devops-testing/toc.yml +++ b/docs/navigate/devops-testing/toc.yml @@ -76,6 +76,8 @@ items: items: - name: Overview href: ../../core/testing/unit-testing-mstest-running-tests.md + - name: Test WinUI 3 apps + href: ../../core/testing/unit-testing-mstest-winui.md - name: Configure MSTest href: ../../core/testing/unit-testing-mstest-configure.md - name: MSTest SDK