UI tests can pass on a developer's machine and still fail in a restricted test environment. The reason is not always a problem with the application or the test assertions. Windows security boundaries, process permissions, desktop access, and application packaging can all affect how a UI test runs.
Running MSTest UI tests inside an AppContainer introduces an additional challenge: the test process operates with restricted access to system resources. Developers need to understand which operations are permitted, how the test process interacts with the Windows desktop, and how to diagnose failures that do not occur during ordinary test execution.
This article explains the key concepts, a practical MSTest setup, common failure scenarios, and the checks that help make UI tests more reliable in restricted Windows environments.
Understanding AppContainer and MSTest
AppContainer is a Windows application isolation model that restricts access to files, processes, network resources, and other system capabilities. Windows uses this boundary to reduce the impact of a compromised or misbehaving application.
MSTest is a testing framework for .NET applications. It provides test attributes, assertions, lifecycle management, and integration with test execution platforms.
When a UI test runs inside an AppContainer application, the test host must operate within that security boundary. The challenge is not simply starting a test process. The test host must also initialize the correct UI environment, communicate with the test runner, and produce test results without requiring unrestricted system access.
Packaging and AppContainer are different
Packaging an application as MSIX does not automatically mean that it runs inside AppContainer. A packaged WinUI 3 desktop application normally runs with full trust unless its configuration explicitly specifies an AppContainer trust level. UWP applications, by contrast, run within the AppContainer model.
Application model | Security model | Testing consideration |
|---|---|---|
Unpackaged WinUI 3 | Full trust | The test runner can launch the executable directly. |
Packaged WinUI 3 | Usually full trust | Package identity and activation may be required. |
AppContainer WinUI 3 | Restricted trust | The test host and runner need compatible communication and activation. |
UWP | AppContainer | The application model and its UI lifecycle affect test execution. |
This distinction matters when choosing the test runner. A configuration designed for a conventional desktop executable may not work for an AppContainer test host.
Prerequisites for Running MSTest UI Tests
Before configuring the project, verify the development environment.
Install a compatible .NET SDK and Windows development tools.
Use MSTest 4.5 and Microsoft.Testing.Platform 2.5 or later for the AppContainer testing approach described here. Check the release status and compatibility of the packages you install.
Ensure the project targets a supported Windows framework and architecture.
Enable Windows Developer Mode or configure an appropriate application sideloading policy when registering an unsigned package.
Run the test controller from a non-elevated user session.
Verify that the machine running the tests has the required Windows App SDK and application dependencies.
The final two requirements are particularly important. AppContainer testing relies on security boundaries that differ from those of a regular desktop process. Running the controller as an administrator can introduce token and permission differences that prevent communication with the test host.
Configure the MSTest Project
A modern MSTest project can use MSTest.Sdk to simplify test infrastructure configuration. For a WinUI 3 application running inside AppContainer, the project must also use the appropriate Windows application model and package manifest.
The following is an illustrative starting point for a .NET 10 WinUI 3 test application. Keep the Windows App SDK version, application references, and packaging settings aligned with your actual solution.
1. Configure the project file
Create or update the test application's project file:
<Project Sdk="MSTest.Sdk/4.5.0">
<PropertyGroup>
<TargetFramework>
net10.0-windows10.0.19041.0
</TargetFramework>
<OutputType>WinExe</OutputType>
<UseWinUI>true</UseWinUI>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
</PropertyGroup>
</Project>The important settings are:
MSTest.Sdksupplies the MSTest project infrastructure and Microsoft.Testing.Platform integration.TargetFrameworkidentifies the Windows APIs available to the application. The selected Windows target must meet the requirements of the chosen testing setup.OutputTypespecifies that the application produces a Windows executable.UseWinUIenables the WinUI 3 project model.EnableWindowsTargetingallows Windows-targeted projects to be built on supported non-Windows build environments. It does not make UI tests executable on Linux or macOS.
This configuration alone does not enable AppContainer execution. The package manifest and test-host startup mechanism must also match the application's security model.
2. Set the application trust level
For a packaged WinUI 3 application intended to run inside AppContainer, inspect the application declaration in Package.appxmanifest.
The relevant portion of the manifest follows this pattern:
<Applications>
<Application
Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$"
uap10:TrustLevel="appContainer"
uap10:RuntimeBehavior="packagedClassicApp">
<!-- Keep the project's existing visual elements
and other application declarations here. -->
</Application>
</Applications>This is an illustrative fragment, not a complete manifest. Preserve the namespaces, visual elements, extensions, and other declarations required by the project.
The TrustLevel attribute specifies the restricted execution model, while RuntimeBehavior identifies the packaged desktop application behavior. The application manifest must conform to the schema and Windows SDK used by the project.
Do not assume that a successful build proves the application is running inside AppContainer. Verify the package configuration and the actual execution environment.
3. Write a UI test
MSTest UI tests for WinUI and UWP applications need access to the application's real UI environment. A standard test method running on an ordinary thread does not automatically have access to the UI dispatcher.
With a compatible MSTest setup, a UI-thread test can use the following pattern:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.UI.Xaml.Controls;
[TestClass]
public sealed class MainPageTests
{
[UITestMethod]
public async Task GridCanBeCreatedOnUiThread()
{
await Task.Yield();
var grid = new Grid();
Assert.IsNotNull(grid);
Assert.IsTrue(grid.DispatcherQueue.HasThreadAccess);
}
}The example demonstrates a basic UI-thread test rather than end-to-end automation of a running window.
[UITestMethod] identifies a test that requires the supported UI-thread execution model. Creating a WinUI control verifies that the required UI types are available, while DispatcherQueue.HasThreadAccess checks whether the current execution context has access to that dispatcher.
A real application test should also verify relevant application behavior, such as control state, navigation, validation, or user interaction. The test attribute and the application's entry point must be configured according to the selected MSTest version and application model.
Run the Tests
Once the project and manifest are configured, build the application for a specific architecture and execute the test platform through the appropriate MSBuild target.
For an AppContainer WinUI 3 test host, use a non-elevated Developer PowerShell and run:
dotnet build .\MyAppContainerTests.csproj `
-c Release `
-p:Platform=x64
dotnet msbuild .\MyAppContainerTests.csproj `
-t:InvokeTestingPlatform `
-p:Configuration=Release `
-p:Platform=x64 `
"-p:TestingPlatformCommandLineArguments=--report-trx --results-directory C:\TestResults"Replace the project name with your actual project file. The output directory must be writable by the test infrastructure, and the target directory should exist when required by your environment.
The InvokeTestingPlatform target is important because a packaged AppContainer application cannot always be launched and managed like a conventional console-based test executable. The supported launch mechanism coordinates package activation, test execution, and result handling.
The TRX report provides a structured record of test outcomes that can be consumed by compatible reporting tools. The MSBuild invocation should complete with the appropriate exit code so that CI can distinguish a passing test run from a failed one.
How AppContainer Changes Test Execution
A regular test runner generally starts a test process and communicates with it. An AppContainer test host introduces additional restrictions.
The runner may need to activate a packaged application, pass test arguments through the application activation mechanism, establish a communication channel, and retrieve results after execution.
A common source of failure is the communication channel between the test controller and the test host. AppContainer applies restricted security identities, so a named pipe that permits the controller's normal user identity may still deny access to the packaged application.
A compatible Microsoft.Testing.Platform setup handles the necessary package-specific authorization for supported configurations. It should authorize the exact package identity rather than broadly granting access to unrelated applications.
This is why manually changing permissions or disabling security checks is not the preferred solution. Use the supported test infrastructure and retain the intended isolation boundary.
Common Mistakes and Troubleshooting
Problem | Likely cause | Recommended action |
|---|---|---|
Test host cannot connect to the controller | Named-pipe access or incompatible test-platform versions | Verify MSTest and Microsoft.Testing.Platform compatibility and package identity. |
Application fails to activate | Incorrect manifest, architecture, or package registration | Check the manifest, package registration policy, and build architecture. |
UI types fail to initialize | Incorrect application lifecycle or missing UI-thread context | Use the supported UI-test execution model and application entry point. |
Tests pass locally but fail in CI | Different Windows policies, dependencies, or user privileges | Reproduce the CI configuration and run the controller without elevation. |
TRX report is missing | Incorrect report arguments or result collection | Check the test output and use the supported MSBuild invocation. |
Test process remains open | Application shutdown or UI lifecycle issue | Ensure the application exits after the test run completes. |
Diagnose failures systematically
When a test fails, avoid changing permissions or project settings at random. Follow a repeatable diagnostic process.
Confirm the application model. Determine whether the target is UWP, packaged WinUI 3, or unpackaged WinUI 3. These models do not share identical startup requirements.
Check the package manifest. Verify that the trust level and runtime behavior match the intended AppContainer configuration.
Verify tool versions. Confirm that the installed MSTest and Microsoft.Testing.Platform packages support the selected application model.
Check execution privileges. Run the controller from a non-elevated session and verify that the CI agent uses the same approach.
Inspect test output. Separate application startup errors, UI-thread failures, authorization errors, and assertion failures.
Reproduce the failure in isolation. Start with one small UI test before investigating more complicated navigation or interaction scenarios.
This approach helps distinguish infrastructure problems from genuine application defects.
Best Practices for Reliable AppContainer UI Tests
Keep test infrastructure separate from application behavior
Use UI tests for behavior that depends on the actual interface, dispatcher, or packaged application environment. Move ordinary business rules, data transformations, and validation logic into independently testable components wherever possible.
This reduces the number of UI tests needed and makes failures easier to investigate.
Preserve the security boundary
Do not solve test failures by running everything as administrator or granting broad access to system resources. AppContainer exists to restrict access, and weakening that boundary can hide configuration problems.
Use the supported package identity and communication authorization mechanisms.
Make tests deterministic
Avoid relying on fixed delays to assume that a window or control is ready. Prefer explicit readiness conditions and bounded waits supported by the UI testing framework.
Also isolate test data and external dependencies where practical. A test that depends on a shared database, a particular machine state, or an existing application session may behave differently in CI.
Validate the actual CI environment
A successful local run is not enough. Check Windows version, architecture, SDK availability, package registration policy, and execution privileges on the CI agent.
Capture test reports and diagnostic output so that a failed run leaves enough evidence to identify the problem.
Advantages and Disadvantages
Aspect | Advantages | Disadvantages |
|---|---|---|
Security | Tests run within the application's intended restricted environment. | Access restrictions introduce additional configuration requirements. |
Realistic behavior | Helps validate behavior that depends on packaging and AppContainer execution. | Application activation and test-host communication can be more complex. |
CI integration | Structured test reports can support automated pipelines. | Windows-specific dependencies and policies must be maintained. |
Debugging | Reproduces failures associated with restricted execution. | Failures may originate from infrastructure rather than application code. |
AppContainer testing is most useful when the application genuinely runs under that security model. For ordinary business logic or tests that do not depend on the Windows UI environment, a simpler unit-testing approach is usually more efficient.
Summary
Running MSTest UI tests inside an AppContainer requires more than adding test attributes to a project. Developers must configure the correct Windows application model, establish the required UI execution context, use a compatible test platform, and respect the security restrictions imposed on the test host.
The most important practical steps are to verify the package manifest, use the supported AppContainer launch mechanism, run the controller without elevation, and diagnose failures by separating application errors from activation and communication problems.
With these practices, teams can test Windows UI behavior within the intended security boundary while keeping their test infrastructure easier to maintain.

Join the conversation! Your thoughts help the community grow.