ワンクリックで
run-device-tests
// Build and run .NET MAUI device tests locally with category filtering. Supports iOS, MacCatalyst, Android on macOS; Android, Windows on Windows. Use TestFilter to run specific test categories.
// Build and run .NET MAUI device tests locally with category filtering. Supports iOS, MacCatalyst, Android on macOS; Android, Windows on Windows. Use TestFilter to run specific test categories.
Labels issues and pull requests in the dotnet/maui repository with `area-*` and `platform/*` labels ONLY, based on technical content and platform-file conventions. Used by the gh-aw agentic-labeler workflow and available for batch evaluation and interactive Copilot CLI usage.
MAUI-specific dependency flow rules, channel conventions, and feed lookup workflows. Use when asked about darc, BAR, Maestro, feeds for .NET MAUI, build promotion, asset lookup, channel mappings, or dependency flow for dotnet/maui. Wraps the maestro-cli skill and maestro MCP tools with MAUI-specific guardrails.
End-to-end PR reviewer for dotnet/maui. Orchestrates 3 phases — Pre-Flight, Try-Fix, Report. Gate runs separately before this skill. Use when asked to 'review PR #XXXXX', 'work on PR #XXXXX', or 'fix issue #XXXXX'.
Deep code review of PR changes for correctness, safety, and MAUI conventions. Uses independence-first assessment (code before narrative) and delegates to the maui-expert-reviewer agent for per-dimension sub-agent evaluation. Triggers on: "review code for PR", "code review PR", "analyze code changes", "check PR code quality". Do NOT use for: summarizing PRs, describing what changed, general PR questions, running tests, or fixing code.
Attempts ONE alternative fix for a bug, tests it empirically, and reports results. ALWAYS explores a DIFFERENT approach from existing PR fixes. Use when CI or an agent needs to try independent fix alternatives. Invoke with problem description, test command, target files, and optional hints.
Verifies tests catch the bug. Auto-detects test type (UI tests, device tests, unit tests) and dispatches to the appropriate runner. Supports two modes - verify failure only (test creation) or full verification (test + fix validation).
| name | run-device-tests |
| description | Build and run .NET MAUI device tests locally with category filtering. Supports iOS, MacCatalyst, Android on macOS; Android, Windows on Windows. Use TestFilter to run specific test categories. |
| metadata | {"author":"dotnet-maui","version":"2.1"} |
| compatibility | Requires xharness CLI (for iOS/MacCatalyst/Android), Xcode (for Apple platforms), Android SDK (for Android), and .NET SDK with platform workloads. |
Build and run .NET MAUI device tests locally on iOS simulators, MacCatalyst, Android emulators, or Windows.
| Host OS | Supported Platforms |
|---|---|
| macOS | ios, maccatalyst, android |
| Windows | android, windows |
This skill uses bash together with pwsh (PowerShell 7+) to run the PowerShell scripts. Requires:
xharness - Global dotnet tool for running tests on iOS/MacCatalyst/Androiddotnet - .NET SDK with platform workloads installedThis skill uses shared infrastructure scripts:
.github/scripts/shared/Start-Emulator.ps1 - Detects and boots iOS simulators / Android emulators.github/scripts/shared/shared-utils.ps1 - Common utility functionsThese are automatically loaded by the Run-DeviceTests.ps1 script.
| Project | Path |
|---|---|
| Controls | src/Controls/tests/DeviceTests/Controls.DeviceTests.csproj |
| Core | src/Core/tests/DeviceTests/Core.DeviceTests.csproj |
| Essentials | src/Essentials/test/DeviceTests/Essentials.DeviceTests.csproj |
| Graphics | src/Graphics/tests/DeviceTests/Graphics.DeviceTests.csproj |
| BlazorWebView | src/BlazorWebView/tests/DeviceTests/MauiBlazorWebView.DeviceTests.csproj |
| AI | src/AI/tests/Essentials.AI.DeviceTests/Essentials.AI.DeviceTests.csproj |
All scripts are in .github/skills/run-device-tests/scripts/
# Run Controls device tests on iOS simulator (default on macOS)
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform ios
# Run Core device tests on MacCatalyst
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Core -Platform maccatalyst
# Run Controls device tests on Android emulator
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform android
# Run Controls device tests on Windows (default on Windows)
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform windows
# Run on specific iOS version
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Core -Platform ios -iOSVersion 26
# Run with test filter
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform ios -TestFilter "Category=Button"
# Run other test projects
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Essentials -Platform android
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Graphics -Platform maccatalyst
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project BlazorWebView -Platform ios
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform ios -BuildOnly
# iOS simulators
xcrun simctl list devices available
# Android emulators
emulator -list-avds
scripts/Run-DeviceTests.ps1 -Project <name> -Platform <platform> automatically detects/boots device, builds, and runs testsartifacts/log/ directory for detailed test resultsartifacts/bin/<Project>.DeviceTests/<Configuration>/<tfm>/<rid>/artifacts/log/xharness global tool: dotnet tool install --global Microsoft.DotNet.XHarness.CLI# Quick test run for Controls on iOS (default on macOS)
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform ios
# Test on MacCatalyst
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform maccatalyst
# Test on Android emulator (works on both macOS and Windows)
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform android
# Test on Windows (default on Windows)
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform windows
# Test on iOS 26 specifically
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform ios -iOSVersion 26
# Run only Button category tests on iOS
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform ios -TestFilter "Category=Button"
# Build for Android without running tests
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Core -Platform android -BuildOnly
.github/scripts/shared/Start-Emulator.ps1The -TestFilter parameter allows running specific test categories instead of all tests. This is useful for quick iteration during development.
| Format | Description | Example |
|---|---|---|
Category=X | Run only category X | Category=Button |
SkipCategories=X,Y,Z | Skip categories X, Y, Z | SkipCategories=Shell,CollectionView |
# Run only Button tests on iOS
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform ios -TestFilter "Category=Button"
# Run only Button tests on Android
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform android -TestFilter "Category=Button"
# Skip heavy test categories
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform ios -TestFilter "SkipCategories=Shell,CollectionView,HybridWebView"
Test filtering is implemented in src/Core/tests/DeviceTests.Shared/DeviceTestSharedHelpers.cs:
| Platform | How Filter is Passed | How Filter is Read |
|---|---|---|
| iOS/MacCatalyst | --set-env=TestFilter=... | NSProcessInfo.ProcessInfo.Environment["TestFilter"] |
| Android | --arg TestFilter=... | MauiTestInstrumentation.Current.Arguments.GetString("TestFilter") |
| Windows | --filter "Category=..." | Native vstest filter |
Common categories in Controls.DeviceTests:
Button, Label, Entry, Editor - Individual control testsCollectionView, ListView, CarouselView - Collection controls (heavy)Shell, Navigation, TabbedPage - Navigation tests (heavy)Layout, FlexLayout - Layout testsMemory - Memory leak testsAccessibility - Accessibility testsGesture - Gesture recognition testsTo see all categories, check src/Controls/tests/DeviceTests/TestCategory.cs.
If you see errors about Xcode version mismatch (e.g., "Xcode 26.2 installed but 26.0 required"):
# Use -SkipXcodeVersionCheck to bypass validation
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform ios -SkipXcodeVersionCheck
MacCatalyst apps use display names (e.g., "Controls Tests.app") not assembly names. The script handles this automatically by searching for .app bundles in the output directory.
Android package names must be lowercase (e.g., com.microsoft.maui.controls.devicetests). The script has a mapping of project names to correct package names.
Ensure full rebuild: The test filter code must be compiled into the app. Delete artifacts and rebuild:
rm -rf artifacts/bin/<Project>.DeviceTests
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform android -TestFilter "Category=Button"
Check the console output: Look for TestFilter: Category=Button in the test output to confirm filter was applied.
Verify category exists: Ensure the category name matches exactly (case-sensitive).
The script automatically handles XHarness device targeting for iOS and Android:
xcrun simctl to get iOS version from booted simulator--target ios-simulator-64_VERSION and --device UDID to xharness for explicit targeting--target maccatalystemulator-5554)--device-id to xharness android commanddotnet test) for test executionWhy both --target and --device for iOS?
--target ios-simulator-64 (or ios-simulator-64_VERSION) to specify platform type--device UDID explicitly tells xharness which simulator to useExample xharness invocations:
# iOS with test filter
dotnet xharness apple test \
--app path/to/app \
--target ios-simulator-64_18.5 \
--device 56AE278D-60F7-4892-9DE0-6341357CA068 \
-o artifacts/log \
--timeout 01:00:00 \
-v \
--set-env=TestFilter=Category=Button
# MacCatalyst with test filter
dotnet xharness apple test \
--app path/to/app \
--target maccatalyst \
-o artifacts/log \
--timeout 01:00:00 \
-v \
--set-env=TestFilter=Category=Button
# Android with test filter
dotnet xharness android test \
--app path/to/app.apk \
--package-name com.microsoft.maui.controls.devicetests \
--device-id emulator-5554 \
-o artifacts/log \
--timeout 01:00:00 \
-v \
--arg TestFilter=Category=Button
This ensures tests run on the correct device with proper version targeting and filtering.