.NET MAUI
Testing & Debugging
6 question(s)
How do you unit test a MAUI app's logic?
Beginner
Put testable logic in view models and services (plain .NET classes), then test them with xUnit/NUnit/MSTest in a separate class-library targeting a plain TFM (e.g., net8.0). Because MVVM keeps logic out of the UI, you can instantiate view models, inject fakes, and assert on properties and commands without a device.
[Fact]
public async Task Login_SetsIsBusy_False_After_Complete()
{
var vm = new LoginViewModel(new FakeAuth());
await vm.LoginCommand.ExecuteAsync(null);
Assert.False(vm.IsBusy);
}
Real-world example
A team runs hundreds of view-model tests in CI in seconds, with no emulator required.
Common follow-ups: Why keep logic out of code-behind? | What TFM does the test project use?
MVVM
Testing & Debugging
Dependency Injection
How do you mock platform/device services for testing?
Intermediate
Abstract device features behind interfaces (e.g., IGeolocation, IConnectivity—MAUI already provides interfaces for many Essentials APIs) and inject them. In tests supply fakes/mocks. Avoid calling static Essentials members directly in logic; depend on the interface so tests don't touch real hardware.
// Production: inject IConnectivity; Test: pass a stub
public SyncViewModel(IConnectivity connectivity) => _c = connectivity;
var vm = new SyncViewModel(new StubConnectivity(NetworkAccess.None));
Real-world example
A sync view model is tested for its offline path by injecting a stub connectivity that reports no network.
Common follow-ups: Do Essentials expose interfaces? | Why avoid static calls in logic?
Testing & Debugging
Dependency Injection
Device Features
How do you debug platform-specific issues in MAUI?
Intermediate
Select the target platform head in the debugger, use conditional breakpoints and the platform's native logs (logcat for Android, Console/Instruments for iOS). Reproduce on the specific platform, inspect the native view via handlers, and use #if-guarded logging. The Live Visual Tree helps inspect the UI hierarchy.
#if ANDROID
Android.Util.Log.Debug("MyApp", $"State: {state}");
#endif
Real-world example
An Android-only layout glitch is diagnosed by logging to logcat and inspecting the native view tree, then fixed with a handler tweak.
Common follow-ups: Where do Android logs go? | How do you inspect the native view?
Debugging
Platform Integration
Handlers
What is Hot Reload and what are its limitations in MAUI?
Intermediate
XAML Hot Reload applies markup changes to a running app without rebuilding; .NET Hot Reload applies many C# edits live. They speed up UI iteration greatly. Limitations: some structural code changes, new fields, or signature changes require a full rebuild, and not every edit is supported—expect occasional restarts.
Real-world example
A developer tweaks padding and colors in XAML and sees updates instantly on the device, iterating on layout in seconds.
Common follow-ups: What changes force a rebuild? | Does Hot Reload cover C#?
Debugging
XAML & UI Layouts
Productivity
How do you write UI/integration tests for MAUI apps?
Advanced
Use Appium (cross-platform UI automation) or platform tools to drive the running app, asserting on visible elements via automation IDs. Set AutomationId on controls for stable selectors. For device-hosted unit tests, MAUI supports a device test runner. UI tests are slower and more brittle, so cover critical flows and keep most logic in fast unit tests.
<Button Text="Login" AutomationId="LoginButton" />
// Appium: driver.FindElement(MobileBy.AccessibilityId("LoginButton")).Click();
Real-world example
A smoke suite runs the login-to-dashboard flow on real devices nightly via Appium, catching integration regressions.
Common follow-ups: Why set AutomationId? | Why keep most tests at the unit level?
Testing & Debugging
UI Testing
MVVM
How do you capture and diagnose crashes in production MAUI apps?
Advanced
Integrate a crash/telemetry SDK (App Center successor/Sentry/Application Insights) to capture unhandled exceptions with stack traces, device info, and breadcrumbs. Hook AppDomain.UnhandledException and per-platform handlers, symbolicate native crashes with debug symbols, and monitor crash-free rates per release.
AppDomain.CurrentDomain.UnhandledException += (s, e) =>
_telemetry.TrackException((Exception)e.ExceptionObject);
Real-world example
A spike in crashes after a release is pinpointed to one device model via telemetry stack traces and hotfixed the same day.
Common follow-ups: How do you symbolicate native crashes? | What is a crash-free rate?
Debugging
Deployment
Monitoring