Testing Model
Split tests by what they need from Windows.
Test Layers
| Layer | Tool | Runs where |
|---|---|---|
| Pure logic | MSTest, NUnit, or xUnit | Fast local Windows CI/dev shell |
| XAML runtime | WinUI Unit Test App, [UITestMethod] | Windows with WinUI test host |
| Native UI automation | Appium with Windows driver | Windows desktop session |
| Accessibility | Accessibility Insights for Windows | Windows desktop session |
| WebView2 web content | Playwright | Windows with WebView2 target |
| Package/release | WACK and Store validation | Windows machine and/or Partner Center |
Keep Logic Out Of XAML
Move business logic into a core library:
MyApp.Core -> normal unit tests
MyApp -> WinUI app shell
MyApp.WinUITests -> XAML/UI-thread tests only
This keeps most tests fast and avoids requiring a XAML runtime for every assertion.
XAML Test Example
[TestClass]
public class WindowTests
{
[UITestMethod]
public void CreatesGrid()
{
var grid = new Microsoft.UI.Xaml.Controls.Grid();
Assert.AreEqual(0, grid.MinWidth);
}
}
Use [UITestMethod] when the test touches XAML objects that require a UI thread.
UI Automation
Use AutomationProperties.AutomationId on important controls so Appium and Accessibility Insights can find stable targets.
<Button
Content="Save"
AutomationProperties.AutomationId="SaveButton" />
Gotcha: A normal unit test project can test pure code, but it is the wrong host for XAML runtime behavior unless you follow the target framework, runtime identifier, and bootstrap guidance.