Xamarin / .NET MAUI Testing Guide (2026)

.NET MAUI (successor to Xamarin.Forms) brings cross-platform C# apps to iOS, Android, Windows, macOS. Testing them covers the shared logic in C#, platform-specific bindings, and the UI layer. This gui

April 21, 2026 · 3 min read · Testing Guides

.NET MAUI (successor to Xamarin.Forms) brings cross-platform C# apps to iOS, Android, Windows, macOS. Testing them covers the shared logic in C#, platform-specific bindings, and the UI layer. This guide is the 2026 approach.

The stack

Unit tests

xUnit is the go-to:


public class LoginViewModelTests
{
    [Fact]
    public async Task Login_with_valid_creds_sets_authenticated()
    {
        var mockAuth = new Mock<IAuthService>();
        mockAuth.Setup(a => a.Login(It.IsAny<string>(), It.IsAny<string>()))
                .ReturnsAsync(AuthResult.Success);
        var vm = new LoginViewModel(mockAuth.Object);
        await vm.Login("test@example.com", "correct");
        Assert.Equal(AuthState.Authenticated, vm.State);
    }
}

Fast, deterministic, no UI required.

UI tests

Appium + UITest (Xamarin.UITest / Maui-specific)


[Test]
public void Login_happy_path()
{
    app.WaitForElement(c => c.Marked("email"));
    app.Tap(c => c.Marked("email"));
    app.EnterText("test@example.com");
    app.Tap(c => c.Marked("password"));
    app.EnterText("correct");
    app.Tap(c => c.Marked("sign_in"));
    app.WaitForElement(c => c.Marked("home"));
}

AutomationId on XAML elements is the canonical locator:


<Button Text="Sign In" AutomationId="sign_in" Clicked="OnSignIn" />

Appium direct


var driver = new AndroidDriver(new Uri("http://localhost:4723"), options);
driver.FindElement(MobileBy.AccessibilityId("sign_in")).Click();

Portable test code across Android + iOS.

Snapshot tests

.NET MAUI has no first-class snapshot tool. Options:

Not as mature as iOS / Android native. Investment required.

Platform-specific

Handler tests: verify custom handler on Android behaves correctly vs iOS:


public class MyCustomHandler : ViewHandler<MyCustomView, PlatformViewType>
{
    // Platform-specific wiring
}

Test with Xamarin.UITest or Appium on each platform — same test code, different build.

CI


# On each PR
- run: dotnet test --configuration Release

# Platform-specific UI tests
- run: dotnet test --configuration Release --filter Platform=Android
  # requires Android SDK + emulator in CI

Gotchas

Binding errors silent

XAML binding typo does not throw; it silently shows nothing. Tests should assert expected values visible.

Lifecycle

OnAppearing / OnDisappearing ordering different from WPF / other XAML.

Async in ViewModel

Async void is common antipattern; use async Task and await properly in tests.

Different behavior across platforms

UI tests passing on Android do not mean iOS works. Run matrix.

How SUSA tests MAUI apps

SUSA drives MAUI apps via Android Accessibility (Android target) or Appium (iOS target). AutomationId maps to accessibility-id. Generated Appium scripts work for MAUI as for any other native app.


susatest-agent test mauiapp.apk --persona curious --steps 200

Best practices

  1. Shared logic in testable ViewModels. 80% of code is testable without UI.
  2. AutomationId on every interactive. Stable locators.
  3. UI tests for critical flows only. Slow and flakier.
  4. Run on both platforms. Parity is not automatic.
  5. Snapshot testing when time allows. Not mature, but worth investment.

MAUI testing is less mature than SwiftUI / Compose. The C# shared logic covers more than native frameworks would, offsetting somewhat. Focus on ViewModel tests; add UI tests for the critical 10%.

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free