docs/design/UITesting-Architecture.md
This document covers the architecture decisions, CI/CD integration, and advanced topics for .NET MAUI UI testing.
For day-to-day test writing, see UITesting-Guide.md.
This document focuses on architecture, CI/CD integration, and advanced topics for .NET MAUI UI testing. For basic concepts and API reference, see the UITesting-Guide.md.
When working on a single test case, you can bypass the test selection UI and launch directly to your issue page:
src/Controls/tests/TestCases.HostApp/MauiProgram.user.cs (not tracked by git):using Controls.TestCases.HostApp.Issues;
namespace Maui.Controls.Sample;
public partial class MauiProgram
{
static partial void OverrideMainPage(ref Page mainPage)
{
mainPage = new Issue99999(); // Your issue number here
}
}
Benefits:
Testing against saved screenshots from CI is important for visual regression testing. Here's how to set up screenshot verification:
[Test]
public void MyVisualTest()
{
App.WaitForElement("MyElement");
// ... test interactions ...
VerifyScreenshot(); // Call at end of test
}
Create a PR with your test
Wait for CI to run
At the bottom of your PR, find the checks section
Locate Maui-UITestpublic (marked as required) and click Details
Click "View More Details on Azure Pipelines"
On the summary page, find the box with "Related" and click Consumed
Click the three dots next to "Drop" and download
Unzip the downloaded artifact
Navigate to Controls.TestCases.Shared/ folder to find your snapshot
Add the .png file to the appropriate platform-specific snapshots folder:
src/Controls/tests/TestCases.Android.Tests/snapshots/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/src/Controls/tests/TestCases.Windows.Tests/snapshots/src/Controls/tests/TestCases.Mac.Tests/snapshots/Important: File name must match your test method name exactly
Note: iOS has ios/ and ios-iphonex/ subfolders - only submit to ios/
Commit and push to your PR
When tests fail, CI produces comparison screenshots showing differences:
-diff suffixGallery tests run the same set of tests across multiple controls. When creating a new control, add a gallery page.
Base Classes:
Derive from these to automatically get standard test interactions for your control.
By default, all test methods in a class run in the same app instance. The app restarts when moving to the next test class.
To restart the app after each test method:
public class MyIssueTests : _IssuesUITest
{
protected override bool ResetAfterEachTest => true;
// Each test method below will get a fresh app instance
}
Use this when:
Use preprocessor directives when tests can't run on all platforms:
#if !MACCATALYST
[Test]
public void ScreenshotTest()
{
// This test won't appear on MacCatalyst
VerifyScreenshot();
}
#endif
Common scenarios:
VerifyScreenshot() doesn't work on MacCatalyst (yet)When compiling for that platform, the test won't appear in the test list.
Access logs from CI builds using the same "Drop" artifact download process as screenshots.
All Platforms:
appium_<platform_name>.log - Appium driver outputiOS:
logarchive files - Console output from simulatorAndroid:
logcat file - Only present if test failed or device crashedWindows & Mac:
WaitForElement callsVerifyScreenshot() not currently supported on MacCatalyst#if !MACCATALYST to skip screenshot tests on Catalyst