diff --git a/.cirrus.yml b/.cirrus.yml
index 96902cf..edefc19 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -125,7 +125,7 @@
     memory: 12G
   matrix:
     ### Android tasks ###
-    - name: build-apks+java-test+firebase-test-lab
+    - name: build-apks+android-unit+firebase-test-lab
       env:
         matrix:
           PLUGIN_SHARDING: "--shardIndex 0 --shardCount 4"
@@ -160,13 +160,15 @@
         - export CIRRUS_CHANGE_MESSAGE=""
         - export CIRRUS_COMMIT_MESSAGE=""
         - ./script/tool_runner.sh build-examples --apk
-      java_test_script:
+      native_unit_test_script:
         # Unsetting CIRRUS_CHANGE_MESSAGE and CIRRUS_COMMIT_MESSAGE as they
         # might include non-ASCII characters which makes Gradle crash.
         # TODO(stuartmorgan): See https://github.com/flutter/flutter/issues/24935
         - export CIRRUS_CHANGE_MESSAGE=""
         - export CIRRUS_COMMIT_MESSAGE=""
-        - ./script/tool_runner.sh java-test  # must come after apk build
+        # Native integration tests are handled by firebase-test-lab below, so
+        # only run unit tests.
+        - ./script/tool_runner.sh native-test --android --no-integration  # must come after apk build
       firebase_test_lab_script:
         # Unsetting CIRRUS_CHANGE_MESSAGE and CIRRUS_COMMIT_MESSAGE as they
         # might include non-ASCII characters which makes Gradle crash.
@@ -239,12 +241,12 @@
         - ./script/tool_runner.sh build-examples --ios
       xcode_analyze_script:
         - ./script/tool_runner.sh xcode-analyze --ios
-      xctest_script:
-        - ./script/tool_runner.sh xctest --ios --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=latest"
+      native_test_script:
+        - ./script/tool_runner.sh native-test --ios --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=latest"
       drive_script:
         # `drive-examples` contains integration tests, which changes the UI of the application.
         # This UI change sometimes affects `xctest`.
-        # So we run `drive-examples` after `xctest`, changing the order will result ci failure.
+        # So we run `drive-examples` after `native-test`; changing the order will result ci failure.
         - ./script/tool_runner.sh drive-examples --ios --exclude $PLUGINS_TO_EXCLUDE_INTEGRATION_TESTS
     ### macOS desktop tasks ###
     - name: build_all_plugins_macos
@@ -269,7 +271,7 @@
         - ./script/tool_runner.sh build-examples --macos
       xcode_analyze_script:
         - ./script/tool_runner.sh xcode-analyze --macos
-      xctest_script:
-        - ./script/tool_runner.sh xctest --macos --exclude $PLUGINS_TO_EXCLUDE_MACOS_XCTESTS
+      native_test_script:
+        - ./script/tool_runner.sh native-test --macos --exclude $PLUGINS_TO_EXCLUDE_MACOS_XCTESTS
       drive_script:
         - ./script/tool_runner.sh drive-examples --macos
diff --git a/script/tool/CHANGELOG.md b/script/tool/CHANGELOG.md
index d701278..dc30c05 100644
--- a/script/tool/CHANGELOG.md
+++ b/script/tool/CHANGELOG.md
@@ -2,13 +2,21 @@
 
 - Added an `xctest` flag to select specific test targets, to allow running only
   unit tests or integration tests.
-- Split Xcode analysis out of `xctest` and into a new `xcode-analyze` command.
+- **Breaking change**: Split Xcode analysis out of `xctest` and into a new
+  `xcode-analyze` command.
 - Fixed a bug that caused `firebase-test-lab` to hang if it tried to run more
   than one plugin's tests in a single run.
 - **Breaking change**: If `firebase-test-lab` is run on a package that supports
   Android, but for which no tests are run, it now fails instead of skipping.
   This matches `drive-examples`, as this command is what is used for driving
   Android Flutter integration tests on CI.
+- **Breaking change**: Replaced `xctest` with a new `native-test` command that
+  will eventually be able to run native unit and integration tests for all
+  platforms.
+  - Adds the ability to disable test types via `--no-unit` or
+    `--no-integration`.
+- **Breaking change**: Replaced `java-test` with Android unit test support for
+  the new `native-test` command.
 
 ## 0.4.1
 
diff --git a/script/tool/README.md b/script/tool/README.md
index 5629dc5..1a87f09 100644
--- a/script/tool/README.md
+++ b/script/tool/README.md
@@ -75,14 +75,28 @@
 dart run ./script/tool/bin/flutter_plugin_tools.dart test --packages plugin_name
 ```
 
-### Run XCTests
+### Run Dart Integration Tests
 
 ```sh
 cd <repository root>
-# For iOS:
-dart run ./script/tool/bin/flutter_plugin_tools.dart xctest --ios --packages plugin_name
-# For macOS:
-dart run ./script/tool/bin/flutter_plugin_tools.dart xctest --macos --packages plugin_name
+dart run ./script/tool/bin/flutter_plugin_tools.dart build-examples --packages plugin_name
+dart run ./script/tool/bin/flutter_plugin_tools.dart drive-examples --packages plugin_name
+```
+
+### Run Native Tests
+
+`native-test` takes one or more platform flags to run tests for. By default it
+runs both unit tests and (on platforms that support it) integration tests, but
+`--no-unit` or `--no-integration` can be used to run just one type.
+
+Examples:
+
+```sh
+cd <repository root>
+# Run just unit tests for iOS and Android:
+dart run ./script/tool/bin/flutter_plugin_tools.dart native-test --ios --android --no-integration --packages plugin_name
+# Run all tests for macOS:
+dart run ./script/tool/bin/flutter_plugin_tools.dart native-test --macos --packages plugin_name
 ```
 
 ### Publish a Release
diff --git a/script/tool/lib/src/common/package_looping_command.dart b/script/tool/lib/src/common/package_looping_command.dart
index 9f4039e..0bcde6d 100644
--- a/script/tool/lib/src/common/package_looping_command.dart
+++ b/script/tool/lib/src/common/package_looping_command.dart
@@ -165,9 +165,9 @@
     final List<String> components = p.posix.split(packageName);
     // For the common federated plugin pattern of `foo/foo_subpackage`, drop
     // the first part since it's not useful.
-    if (components.length == 2 &&
+    if (components.length >= 2 &&
         components[1].startsWith('${components[0]}_')) {
-      packageName = components[1];
+      packageName = p.posix.joinAll(components.sublist(1));
     }
     return packageName;
   }
diff --git a/script/tool/lib/src/java_test_command.dart b/script/tool/lib/src/java_test_command.dart
deleted file mode 100644
index b36d110..0000000
--- a/script/tool/lib/src/java_test_command.dart
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:file/file.dart';
-import 'package:platform/platform.dart';
-
-import 'common/core.dart';
-import 'common/package_looping_command.dart';
-import 'common/process_runner.dart';
-
-/// A command to run the Java tests of Android plugins.
-class JavaTestCommand extends PackageLoopingCommand {
-  /// Creates an instance of the test runner.
-  JavaTestCommand(
-    Directory packagesDir, {
-    ProcessRunner processRunner = const ProcessRunner(),
-    Platform platform = const LocalPlatform(),
-  }) : super(packagesDir, processRunner: processRunner, platform: platform);
-
-  static const String _gradleWrapper = 'gradlew';
-
-  @override
-  final String name = 'java-test';
-
-  @override
-  final String description = 'Runs the Java tests of the example apps.\n\n'
-      'Building the apks of the example apps is required before executing this'
-      'command.';
-
-  @override
-  Future<PackageResult> runForPackage(Directory package) async {
-    final Iterable<Directory> examplesWithTests = getExamplesForPlugin(package)
-        .where((Directory d) =>
-            isFlutterPackage(d) &&
-            (d
-                    .childDirectory('android')
-                    .childDirectory('app')
-                    .childDirectory('src')
-                    .childDirectory('test')
-                    .existsSync() ||
-                d.parent
-                    .childDirectory('android')
-                    .childDirectory('src')
-                    .childDirectory('test')
-                    .existsSync()));
-
-    if (examplesWithTests.isEmpty) {
-      return PackageResult.skip('No Java unit tests.');
-    }
-
-    final List<String> errors = <String>[];
-    for (final Directory example in examplesWithTests) {
-      final String exampleName = getRelativePosixPath(example, from: package);
-      print('\nRUNNING JAVA TESTS for $exampleName');
-
-      final Directory androidDirectory = example.childDirectory('android');
-      final File gradleFile = androidDirectory.childFile(_gradleWrapper);
-      if (!gradleFile.existsSync()) {
-        printError('ERROR: Run "flutter build apk" on $exampleName, or run '
-            'this tool\'s "build-examples --apk" command, '
-            'before executing tests.');
-        errors.add('$exampleName has not been built.');
-        continue;
-      }
-
-      final int exitCode = await processRunner.runAndStream(
-          gradleFile.path, <String>['testDebugUnitTest', '--info'],
-          workingDir: androidDirectory);
-      if (exitCode != 0) {
-        errors.add('$exampleName tests failed.');
-      }
-    }
-    return errors.isEmpty
-        ? PackageResult.success()
-        : PackageResult.fail(errors);
-  }
-}
diff --git a/script/tool/lib/src/main.dart b/script/tool/lib/src/main.dart
index ef1a18a..6001c5d 100644
--- a/script/tool/lib/src/main.dart
+++ b/script/tool/lib/src/main.dart
@@ -15,17 +15,16 @@
 import 'drive_examples_command.dart';
 import 'firebase_test_lab_command.dart';
 import 'format_command.dart';
-import 'java_test_command.dart';
 import 'license_check_command.dart';
 import 'lint_podspecs_command.dart';
 import 'list_command.dart';
+import 'native_test_command.dart';
 import 'publish_check_command.dart';
 import 'publish_plugin_command.dart';
 import 'pubspec_check_command.dart';
 import 'test_command.dart';
 import 'version_check_command.dart';
 import 'xcode_analyze_command.dart';
-import 'xctest_command.dart';
 
 void main(List<String> args) {
   const FileSystem fileSystem = LocalFileSystem();
@@ -51,17 +50,16 @@
     ..addCommand(DriveExamplesCommand(packagesDir))
     ..addCommand(FirebaseTestLabCommand(packagesDir))
     ..addCommand(FormatCommand(packagesDir))
-    ..addCommand(JavaTestCommand(packagesDir))
     ..addCommand(LicenseCheckCommand(packagesDir))
     ..addCommand(LintPodspecsCommand(packagesDir))
     ..addCommand(ListCommand(packagesDir))
+    ..addCommand(NativeTestCommand(packagesDir))
     ..addCommand(PublishCheckCommand(packagesDir))
     ..addCommand(PublishPluginCommand(packagesDir))
     ..addCommand(PubspecCheckCommand(packagesDir))
     ..addCommand(TestCommand(packagesDir))
     ..addCommand(VersionCheckCommand(packagesDir))
-    ..addCommand(XcodeAnalyzeCommand(packagesDir))
-    ..addCommand(XCTestCommand(packagesDir));
+    ..addCommand(XcodeAnalyzeCommand(packagesDir));
 
   commandRunner.run(args).catchError((Object e) {
     final ToolExit toolExit = e as ToolExit;
diff --git a/script/tool/lib/src/native_test_command.dart b/script/tool/lib/src/native_test_command.dart
new file mode 100644
index 0000000..73a435d
--- /dev/null
+++ b/script/tool/lib/src/native_test_command.dart
@@ -0,0 +1,377 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:platform/platform.dart';
+
+import 'common/core.dart';
+import 'common/package_looping_command.dart';
+import 'common/plugin_utils.dart';
+import 'common/process_runner.dart';
+import 'common/xcode.dart';
+
+const String _unitTestFlag = 'unit';
+const String _integrationTestFlag = 'integration';
+
+const String _iosDestinationFlag = 'ios-destination';
+
+const int _exitNoIosSimulators = 3;
+
+/// The command to run native tests for plugins:
+/// - iOS and macOS: XCTests (XCUnitTest and XCUITest) in plugins.
+class NativeTestCommand extends PackageLoopingCommand {
+  /// Creates an instance of the test command.
+  NativeTestCommand(
+    Directory packagesDir, {
+    ProcessRunner processRunner = const ProcessRunner(),
+    Platform platform = const LocalPlatform(),
+  })  : _xcode = Xcode(processRunner: processRunner, log: true),
+        super(packagesDir, processRunner: processRunner, platform: platform) {
+    argParser.addOption(
+      _iosDestinationFlag,
+      help: 'Specify the destination when running iOS tests.\n'
+          'This is passed to the `-destination` argument in the xcodebuild command.\n'
+          'See https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-UNIT '
+          'for details on how to specify the destination.',
+    );
+    argParser.addFlag(kPlatformAndroid, help: 'Runs Android tests');
+    argParser.addFlag(kPlatformIos, help: 'Runs iOS tests');
+    argParser.addFlag(kPlatformMacos, help: 'Runs macOS tests');
+
+    // By default, both unit tests and integration tests are run, but provide
+    // flags to disable one or the other.
+    argParser.addFlag(_unitTestFlag,
+        help: 'Runs native unit tests', defaultsTo: true);
+    argParser.addFlag(_integrationTestFlag,
+        help: 'Runs native integration (UI) tests', defaultsTo: true);
+  }
+
+  static const String _gradleWrapper = 'gradlew';
+
+  // The device destination flags for iOS tests.
+  List<String> _iosDestinationFlags = <String>[];
+
+  final Xcode _xcode;
+
+  @override
+  final String name = 'native-test';
+
+  @override
+  final String description = '''
+Runs native unit tests and native integration tests.
+
+Currently supported platforms:
+- Android (unit tests only)
+- iOS: requires 'xcrun' to be in your path.
+- macOS: requires 'xcrun' to be in your path.
+
+The example app(s) must be built for all targeted platforms before running
+this command.
+''';
+
+  Map<String, _PlatformDetails> _platforms = <String, _PlatformDetails>{};
+
+  List<String> _requestedPlatforms = <String>[];
+
+  @override
+  Future<void> initializeRun() async {
+    _platforms = <String, _PlatformDetails>{
+      kPlatformAndroid: _PlatformDetails('Android', _testAndroid),
+      kPlatformIos: _PlatformDetails('iOS', _testIos),
+      kPlatformMacos: _PlatformDetails('macOS', _testMacOS),
+    };
+    _requestedPlatforms = _platforms.keys
+        .where((String platform) => getBoolArg(platform))
+        .toList();
+    _requestedPlatforms.sort();
+
+    if (_requestedPlatforms.isEmpty) {
+      printError('At least one platform flag must be provided.');
+      throw ToolExit(exitInvalidArguments);
+    }
+
+    if (!(getBoolArg(_unitTestFlag) || getBoolArg(_integrationTestFlag))) {
+      printError('At least one test type must be enabled.');
+      throw ToolExit(exitInvalidArguments);
+    }
+
+    if (getBoolArg(kPlatformAndroid) && getBoolArg(_integrationTestFlag)) {
+      logWarning('This command currently only supports unit tests for Android. '
+          'See https://github.com/flutter/flutter/issues/86490.');
+    }
+
+    // iOS-specific run-level state.
+    if (_requestedPlatforms.contains('ios')) {
+      String destination = getStringArg(_iosDestinationFlag);
+      if (destination.isEmpty) {
+        final String? simulatorId =
+            await _xcode.findBestAvailableIphoneSimulator();
+        if (simulatorId == null) {
+          printError('Cannot find any available iOS simulators.');
+          throw ToolExit(_exitNoIosSimulators);
+        }
+        destination = 'id=$simulatorId';
+      }
+      _iosDestinationFlags = <String>[
+        '-destination',
+        destination,
+      ];
+    }
+  }
+
+  @override
+  Future<PackageResult> runForPackage(Directory package) async {
+    final List<String> testPlatforms = <String>[];
+    for (final String platform in _requestedPlatforms) {
+      if (pluginSupportsPlatform(platform, package,
+          requiredMode: PlatformSupport.inline)) {
+        testPlatforms.add(platform);
+      } else {
+        print('No implementation for ${_platforms[platform]!.label}.');
+      }
+    }
+
+    if (testPlatforms.isEmpty) {
+      return PackageResult.skip('Not implemented for target platform(s).');
+    }
+
+    final _TestMode mode = _TestMode(
+      unit: getBoolArg(_unitTestFlag),
+      integration: getBoolArg(_integrationTestFlag),
+    );
+
+    bool ranTests = false;
+    bool failed = false;
+    final List<String> failureMessages = <String>[];
+    for (final String platform in testPlatforms) {
+      final _PlatformDetails platformInfo = _platforms[platform]!;
+      print('Running tests for ${platformInfo.label}...');
+      print('----------------------------------------');
+      final _PlatformResult result =
+          await platformInfo.testFunction(package, mode);
+      ranTests |= result.state != RunState.skipped;
+      if (result.state == RunState.failed) {
+        failed = true;
+
+        final String? error = result.error;
+        // Only provide the failing platforms in the failure details if testing
+        // multiple platforms, otherwise it's just noise.
+        if (_requestedPlatforms.length > 1) {
+          failureMessages.add(error != null
+              ? '${platformInfo.label}: $error'
+              : platformInfo.label);
+        } else if (error != null) {
+          // If there's only one platform, only provide error details in the
+          // summary if the platform returned a message.
+          failureMessages.add(error);
+        }
+      }
+    }
+
+    if (!ranTests) {
+      return PackageResult.skip('No tests found.');
+    }
+    return failed
+        ? PackageResult.fail(failureMessages)
+        : PackageResult.success();
+  }
+
+  Future<_PlatformResult> _testAndroid(Directory plugin, _TestMode mode) async {
+    final List<Directory> examplesWithTests = <Directory>[];
+    for (final Directory example in getExamplesForPlugin(plugin)) {
+      if (!isFlutterPackage(example)) {
+        continue;
+      }
+      if (example
+              .childDirectory('android')
+              .childDirectory('app')
+              .childDirectory('src')
+              .childDirectory('test')
+              .existsSync() ||
+          example.parent
+              .childDirectory('android')
+              .childDirectory('src')
+              .childDirectory('test')
+              .existsSync()) {
+        examplesWithTests.add(example);
+      } else {
+        _printNoExampleTestsMessage(example, 'Android');
+      }
+    }
+
+    if (examplesWithTests.isEmpty) {
+      return _PlatformResult(RunState.skipped);
+    }
+
+    bool failed = false;
+    bool hasMissingBuild = false;
+    for (final Directory example in examplesWithTests) {
+      final String exampleName = getPackageDescription(example);
+      _printRunningExampleTestsMessage(example, 'Android');
+
+      final Directory androidDirectory = example.childDirectory('android');
+      final File gradleFile = androidDirectory.childFile(_gradleWrapper);
+      if (!gradleFile.existsSync()) {
+        printError('ERROR: Run "flutter build apk" on $exampleName, or run '
+            'this tool\'s "build-examples --apk" command, '
+            'before executing tests.');
+        failed = true;
+        hasMissingBuild = true;
+        continue;
+      }
+
+      final int exitCode = await processRunner.runAndStream(
+          gradleFile.path, <String>['testDebugUnitTest', '--info'],
+          workingDir: androidDirectory);
+      if (exitCode != 0) {
+        printError('$exampleName tests failed.');
+        failed = true;
+      }
+    }
+    return _PlatformResult(failed ? RunState.failed : RunState.succeeded,
+        error:
+            hasMissingBuild ? 'Examples must be built before testing.' : null);
+  }
+
+  Future<_PlatformResult> _testIos(Directory plugin, _TestMode mode) {
+    return _runXcodeTests(plugin, 'iOS', mode,
+        extraFlags: _iosDestinationFlags);
+  }
+
+  Future<_PlatformResult> _testMacOS(Directory plugin, _TestMode mode) {
+    return _runXcodeTests(plugin, 'macOS', mode);
+  }
+
+  /// Runs all applicable tests for [plugin], printing status and returning
+  /// the test result.
+  ///
+  /// The tests targets must be added to the Xcode project of the example app,
+  /// usually at "example/{ios,macos}/Runner.xcworkspace".
+  Future<_PlatformResult> _runXcodeTests(
+    Directory plugin,
+    String platform,
+    _TestMode mode, {
+    List<String> extraFlags = const <String>[],
+  }) async {
+    String? testTarget;
+    if (mode.unitOnly) {
+      testTarget = 'RunnerTests';
+    } else if (mode.integrationOnly) {
+      testTarget = 'RunnerUITests';
+    }
+
+    // Assume skipped until at least one test has run.
+    RunState overallResult = RunState.skipped;
+    for (final Directory example in getExamplesForPlugin(plugin)) {
+      final String exampleName = getPackageDescription(example);
+
+      if (testTarget != null) {
+        final Directory project = example
+            .childDirectory(platform.toLowerCase())
+            .childDirectory('Runner.xcodeproj');
+        final bool? hasTarget =
+            await _xcode.projectHasTarget(project, testTarget);
+        if (hasTarget == null) {
+          printError('Unable to check targets for $exampleName.');
+          overallResult = RunState.failed;
+          continue;
+        } else if (!hasTarget) {
+          print('No "$testTarget" target in $exampleName; skipping.');
+          continue;
+        }
+      }
+
+      _printRunningExampleTestsMessage(example, platform);
+      final int exitCode = await _xcode.runXcodeBuild(
+        example,
+        actions: <String>['test'],
+        workspace: '${platform.toLowerCase()}/Runner.xcworkspace',
+        scheme: 'Runner',
+        configuration: 'Debug',
+        extraFlags: <String>[
+          if (testTarget != null) '-only-testing:$testTarget',
+          ...extraFlags,
+          'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+        ],
+      );
+
+      // The exit code from 'xcodebuild test' when there are no tests.
+      const int _xcodebuildNoTestExitCode = 66;
+      switch (exitCode) {
+        case _xcodebuildNoTestExitCode:
+          _printNoExampleTestsMessage(example, platform);
+          continue;
+        case 0:
+          printSuccess('Successfully ran $platform xctest for $exampleName');
+          // If this is the first test, assume success until something fails.
+          if (overallResult == RunState.skipped) {
+            overallResult = RunState.succeeded;
+          }
+          break;
+        default:
+          // Any failure means a failure overall.
+          overallResult = RunState.failed;
+          break;
+      }
+    }
+    return _PlatformResult(overallResult);
+  }
+
+  /// Prints a standard format message indicating that [platform] tests for
+  /// [plugin]'s [example] are about to be run.
+  void _printRunningExampleTestsMessage(Directory example, String platform) {
+    print('Running $platform tests for ${getPackageDescription(example)}...');
+  }
+
+  /// Prints a standard format message indicating that no tests were found for
+  /// [plugin]'s [example] for [platform].
+  void _printNoExampleTestsMessage(Directory example, String platform) {
+    print('No $platform tests found for ${getPackageDescription(example)}');
+  }
+}
+
+// The type for a function that takes a plugin directory and runs its native
+// tests for a specific platform.
+typedef _TestFunction = Future<_PlatformResult> Function(Directory, _TestMode);
+
+/// A collection of information related to a specific platform.
+class _PlatformDetails {
+  const _PlatformDetails(
+    this.label,
+    this.testFunction,
+  );
+
+  /// The name to use in output.
+  final String label;
+
+  /// The function to call to run tests.
+  final _TestFunction testFunction;
+}
+
+/// Enabled state for different test types.
+class _TestMode {
+  const _TestMode({required this.unit, required this.integration});
+
+  final bool unit;
+  final bool integration;
+
+  bool get integrationOnly => integration && !unit;
+  bool get unitOnly => unit && !integration;
+}
+
+/// The result of running a single platform's tests.
+class _PlatformResult {
+  _PlatformResult(this.state, {this.error});
+
+  /// The overall state of the platform's tests. This should be:
+  /// - failed if any tests failed.
+  /// - succeeded if at least one test ran, and all tests passed.
+  /// - skipped if no tests ran.
+  final RunState state;
+
+  /// An optional error string to include in the summary for this platform.
+  ///
+  /// Ignored unless [state] is `failed`.
+  final String? error;
+}
diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart
deleted file mode 100644
index 44fc3a8..0000000
--- a/script/tool/lib/src/xctest_command.dart
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:file/file.dart';
-import 'package:platform/platform.dart';
-
-import 'common/core.dart';
-import 'common/package_looping_command.dart';
-import 'common/plugin_utils.dart';
-import 'common/process_runner.dart';
-import 'common/xcode.dart';
-
-const String _iosDestinationFlag = 'ios-destination';
-const String _testTargetFlag = 'test-target';
-
-// The exit code from 'xcodebuild test' when there are no tests.
-const int _xcodebuildNoTestExitCode = 66;
-
-const int _exitNoSimulators = 3;
-
-/// The command to run XCTests (XCUnitTest and XCUITest) in plugins.
-/// The tests target have to be added to the Xcode project of the example app,
-/// usually at "example/{ios,macos}/Runner.xcworkspace".
-class XCTestCommand extends PackageLoopingCommand {
-  /// Creates an instance of the test command.
-  XCTestCommand(
-    Directory packagesDir, {
-    ProcessRunner processRunner = const ProcessRunner(),
-    Platform platform = const LocalPlatform(),
-  })  : _xcode = Xcode(processRunner: processRunner, log: true),
-        super(packagesDir, processRunner: processRunner, platform: platform) {
-    argParser.addOption(
-      _iosDestinationFlag,
-      help:
-          'Specify the destination when running the test, used for -destination flag for xcodebuild command.\n'
-          'this is passed to the `-destination` argument in xcodebuild command.\n'
-          'See https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-UNIT for details on how to specify the destination.',
-    );
-    argParser.addOption(
-      _testTargetFlag,
-      help:
-          'Limits the tests to a specific target (e.g., RunnerTests or RunnerUITests)',
-    );
-    argParser.addFlag(kPlatformIos, help: 'Runs the iOS tests');
-    argParser.addFlag(kPlatformMacos, help: 'Runs the macOS tests');
-  }
-
-  // The device destination flags for iOS tests.
-  List<String> _iosDestinationFlags = <String>[];
-
-  final Xcode _xcode;
-
-  @override
-  final String name = 'xctest';
-
-  @override
-  final String description =
-      'Runs the xctests in the iOS and/or macOS example apps.\n\n'
-      'This command requires "flutter" and "xcrun" to be in your path.';
-
-  @override
-  Future<void> initializeRun() async {
-    final bool shouldTestIos = getBoolArg(kPlatformIos);
-    final bool shouldTestMacos = getBoolArg(kPlatformMacos);
-
-    if (!(shouldTestIos || shouldTestMacos)) {
-      printError('At least one platform flag must be provided.');
-      throw ToolExit(exitInvalidArguments);
-    }
-
-    if (shouldTestIos) {
-      String destination = getStringArg(_iosDestinationFlag);
-      if (destination.isEmpty) {
-        final String? simulatorId =
-            await _xcode.findBestAvailableIphoneSimulator();
-        if (simulatorId == null) {
-          printError('Cannot find any available simulators, tests failed');
-          throw ToolExit(_exitNoSimulators);
-        }
-        destination = 'id=$simulatorId';
-      }
-      _iosDestinationFlags = <String>[
-        '-destination',
-        destination,
-      ];
-    }
-  }
-
-  @override
-  Future<PackageResult> runForPackage(Directory package) async {
-    final bool testIos = getBoolArg(kPlatformIos) &&
-        pluginSupportsPlatform(kPlatformIos, package,
-            requiredMode: PlatformSupport.inline);
-    final bool testMacos = getBoolArg(kPlatformMacos) &&
-        pluginSupportsPlatform(kPlatformMacos, package,
-            requiredMode: PlatformSupport.inline);
-
-    final bool multiplePlatformsRequested =
-        getBoolArg(kPlatformIos) && getBoolArg(kPlatformMacos);
-    if (!(testIos || testMacos)) {
-      String description;
-      if (multiplePlatformsRequested) {
-        description = 'Neither iOS nor macOS is';
-      } else if (getBoolArg(kPlatformIos)) {
-        description = 'iOS is not';
-      } else {
-        description = 'macOS is not';
-      }
-      return PackageResult.skip(
-          '$description implemented by this plugin package.');
-    }
-
-    if (multiplePlatformsRequested && (!testIos || !testMacos)) {
-      print('Only running for ${testIos ? 'iOS' : 'macOS'}\n');
-    }
-
-    final List<String> failures = <String>[];
-    bool ranTests = false;
-    if (testIos) {
-      final RunState result = await _testPlugin(package, 'iOS',
-          extraXcrunFlags: _iosDestinationFlags);
-      ranTests |= result != RunState.skipped;
-      if (result == RunState.failed) {
-        failures.add('iOS');
-      }
-    }
-    if (testMacos) {
-      final RunState result = await _testPlugin(package, 'macOS');
-      ranTests |= result != RunState.skipped;
-      if (result == RunState.failed) {
-        failures.add('macOS');
-      }
-    }
-
-    if (!ranTests) {
-      return PackageResult.skip('No tests found.');
-    }
-    // Only provide the failing platform in the failure details if testing
-    // multiple platforms, otherwise it's just noise.
-    return failures.isEmpty
-        ? PackageResult.success()
-        : PackageResult.fail(
-            multiplePlatformsRequested ? failures : <String>[]);
-  }
-
-  /// Runs all applicable tests for [plugin], printing status and returning
-  /// the test result.
-  Future<RunState> _testPlugin(
-    Directory plugin,
-    String platform, {
-    List<String> extraXcrunFlags = const <String>[],
-  }) async {
-    final String testTarget = getStringArg(_testTargetFlag);
-
-    // Assume skipped until at least one test has run.
-    RunState overallResult = RunState.skipped;
-    for (final Directory example in getExamplesForPlugin(plugin)) {
-      final String examplePath =
-          getRelativePosixPath(example, from: plugin.parent);
-
-      if (testTarget.isNotEmpty) {
-        final Directory project = example
-            .childDirectory(platform.toLowerCase())
-            .childDirectory('Runner.xcodeproj');
-        final bool? hasTarget =
-            await _xcode.projectHasTarget(project, testTarget);
-        if (hasTarget == null) {
-          printError('Unable to check targets for $examplePath.');
-          overallResult = RunState.failed;
-          continue;
-        } else if (!hasTarget) {
-          print('No "$testTarget" target in $examplePath; skipping.');
-          continue;
-        }
-      }
-
-      print('Running $platform tests for $examplePath...');
-      final int exitCode = await _xcode.runXcodeBuild(
-        example,
-        actions: <String>['test'],
-        workspace: '${platform.toLowerCase()}/Runner.xcworkspace',
-        scheme: 'Runner',
-        configuration: 'Debug',
-        extraFlags: <String>[
-          if (testTarget.isNotEmpty) '-only-testing:$testTarget',
-          ...extraXcrunFlags,
-          'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-        ],
-      );
-
-      switch (exitCode) {
-        case _xcodebuildNoTestExitCode:
-          print('No tests found for $examplePath');
-          continue;
-        case 0:
-          printSuccess('Successfully ran $platform xctest for $examplePath');
-          // If this is the first test, assume success until something fails.
-          if (overallResult == RunState.skipped) {
-            overallResult = RunState.succeeded;
-          }
-          break;
-        default:
-          // Any failure means a failure overall.
-          overallResult = RunState.failed;
-          break;
-      }
-    }
-    return overallResult;
-  }
-}
diff --git a/script/tool/test/java_test_command_test.dart b/script/tool/test/java_test_command_test.dart
deleted file mode 100644
index 13e0e7f..0000000
--- a/script/tool/test/java_test_command_test.dart
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:io' as io;
-
-import 'package:args/command_runner.dart';
-import 'package:file/file.dart';
-import 'package:file/memory.dart';
-import 'package:flutter_plugin_tools/src/common/core.dart';
-import 'package:flutter_plugin_tools/src/common/plugin_utils.dart';
-import 'package:flutter_plugin_tools/src/java_test_command.dart';
-import 'package:test/test.dart';
-
-import 'mocks.dart';
-import 'util.dart';
-
-void main() {
-  group('$JavaTestCommand', () {
-    late FileSystem fileSystem;
-    late MockPlatform mockPlatform;
-    late Directory packagesDir;
-    late CommandRunner<void> runner;
-    late RecordingProcessRunner processRunner;
-
-    setUp(() {
-      fileSystem = MemoryFileSystem();
-      mockPlatform = MockPlatform();
-      packagesDir = createPackagesDirectory(fileSystem: fileSystem);
-      processRunner = RecordingProcessRunner();
-      final JavaTestCommand command = JavaTestCommand(
-        packagesDir,
-        processRunner: processRunner,
-        platform: mockPlatform,
-      );
-
-      runner =
-          CommandRunner<void>('java_test_test', 'Test for $JavaTestCommand');
-      runner.addCommand(command);
-    });
-
-    test('Should run Java tests in Android implementation folder', () async {
-      final Directory plugin = createFakePlugin(
-        'plugin1',
-        packagesDir,
-        platformSupport: <String, PlatformSupport>{
-          kPlatformAndroid: PlatformSupport.inline
-        },
-        extraFiles: <String>[
-          'example/android/gradlew',
-          'android/src/test/example_test.java',
-        ],
-      );
-
-      await runCapturingPrint(runner, <String>['java-test']);
-
-      final Directory androidFolder =
-          plugin.childDirectory('example').childDirectory('android');
-
-      expect(
-        processRunner.recordedCalls,
-        orderedEquals(<ProcessCall>[
-          ProcessCall(
-            androidFolder.childFile('gradlew').path,
-            const <String>['testDebugUnitTest', '--info'],
-            androidFolder.path,
-          ),
-        ]),
-      );
-    });
-
-    test('Should run Java tests in example folder', () async {
-      final Directory plugin = createFakePlugin(
-        'plugin1',
-        packagesDir,
-        platformSupport: <String, PlatformSupport>{
-          kPlatformAndroid: PlatformSupport.inline
-        },
-        extraFiles: <String>[
-          'example/android/gradlew',
-          'example/android/app/src/test/example_test.java',
-        ],
-      );
-
-      await runCapturingPrint(runner, <String>['java-test']);
-
-      final Directory androidFolder =
-          plugin.childDirectory('example').childDirectory('android');
-
-      expect(
-        processRunner.recordedCalls,
-        orderedEquals(<ProcessCall>[
-          ProcessCall(
-            androidFolder.childFile('gradlew').path,
-            const <String>['testDebugUnitTest', '--info'],
-            androidFolder.path,
-          ),
-        ]),
-      );
-    });
-
-    test('fails when the app needs to be built', () async {
-      createFakePlugin(
-        'plugin1',
-        packagesDir,
-        platformSupport: <String, PlatformSupport>{
-          kPlatformAndroid: PlatformSupport.inline
-        },
-        extraFiles: <String>[
-          'example/android/app/src/test/example_test.java',
-        ],
-      );
-
-      Error? commandError;
-      final List<String> output = await runCapturingPrint(
-          runner, <String>['java-test'], errorHandler: (Error e) {
-        commandError = e;
-      });
-
-      expect(commandError, isA<ToolExit>());
-
-      expect(
-        output,
-        containsAllInOrder(<Matcher>[
-          contains('ERROR: Run "flutter build apk" on example'),
-          contains('plugin1:\n'
-              '    example has not been built.')
-        ]),
-      );
-    });
-
-    test('fails when a test fails', () async {
-      final Directory pluginDir = createFakePlugin(
-        'plugin1',
-        packagesDir,
-        platformSupport: <String, PlatformSupport>{
-          kPlatformAndroid: PlatformSupport.inline
-        },
-        extraFiles: <String>[
-          'example/android/gradlew',
-          'example/android/app/src/test/example_test.java',
-        ],
-      );
-
-      final String gradlewPath = pluginDir
-          .childDirectory('example')
-          .childDirectory('android')
-          .childFile('gradlew')
-          .path;
-      processRunner.mockProcessesForExecutable[gradlewPath] = <io.Process>[
-        MockProcess.failing()
-      ];
-
-      Error? commandError;
-      final List<String> output = await runCapturingPrint(
-          runner, <String>['java-test'], errorHandler: (Error e) {
-        commandError = e;
-      });
-
-      expect(commandError, isA<ToolExit>());
-
-      expect(
-        output,
-        containsAllInOrder(<Matcher>[
-          contains('plugin1:\n'
-              '    example tests failed.')
-        ]),
-      );
-    });
-
-    test('Skips when running no tests', () async {
-      createFakePlugin(
-        'plugin1',
-        packagesDir,
-      );
-
-      final List<String> output =
-          await runCapturingPrint(runner, <String>['java-test']);
-
-      expect(
-        output,
-        containsAllInOrder(
-            <Matcher>[contains('SKIPPING: No Java unit tests.')]),
-      );
-    });
-  });
-}
diff --git a/script/tool/test/native_test_command_test.dart b/script/tool/test/native_test_command_test.dart
new file mode 100644
index 0000000..ca28a6c
--- /dev/null
+++ b/script/tool/test/native_test_command_test.dart
@@ -0,0 +1,1071 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io' as io;
+
+import 'package:args/command_runner.dart';
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:flutter_plugin_tools/src/common/core.dart';
+import 'package:flutter_plugin_tools/src/common/plugin_utils.dart';
+import 'package:flutter_plugin_tools/src/native_test_command.dart';
+import 'package:test/test.dart';
+
+import 'mocks.dart';
+import 'util.dart';
+
+final Map<String, dynamic> _kDeviceListMap = <String, dynamic>{
+  'runtimes': <Map<String, dynamic>>[
+    <String, dynamic>{
+      'bundlePath':
+          '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime',
+      'buildversion': '17L255',
+      'runtimeRoot':
+          '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime/Contents/Resources/RuntimeRoot',
+      'identifier': 'com.apple.CoreSimulator.SimRuntime.iOS-13-4',
+      'version': '13.4',
+      'isAvailable': true,
+      'name': 'iOS 13.4'
+    },
+  ],
+  'devices': <String, dynamic>{
+    'com.apple.CoreSimulator.SimRuntime.iOS-13-4': <Map<String, dynamic>>[
+      <String, dynamic>{
+        'dataPath':
+            '/Users/xxx/Library/Developer/CoreSimulator/Devices/1E76A0FD-38AC-4537-A989-EA639D7D012A/data',
+        'logPath':
+            '/Users/xxx/Library/Logs/CoreSimulator/1E76A0FD-38AC-4537-A989-EA639D7D012A',
+        'udid': '1E76A0FD-38AC-4537-A989-EA639D7D012A',
+        'isAvailable': true,
+        'deviceTypeIdentifier':
+            'com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus',
+        'state': 'Shutdown',
+        'name': 'iPhone 8 Plus'
+      }
+    ]
+  }
+};
+
+// TODO(stuartmorgan): Rework these tests to use a mock Xcode instead of
+// doing all the process mocking and validation.
+void main() {
+  const String _kDestination = '--ios-destination';
+
+  group('test native_test_command', () {
+    late FileSystem fileSystem;
+    late MockPlatform mockPlatform;
+    late Directory packagesDir;
+    late CommandRunner<void> runner;
+    late RecordingProcessRunner processRunner;
+
+    setUp(() {
+      fileSystem = MemoryFileSystem();
+      mockPlatform = MockPlatform(isMacOS: true);
+      packagesDir = createPackagesDirectory(fileSystem: fileSystem);
+      processRunner = RecordingProcessRunner();
+      final NativeTestCommand command = NativeTestCommand(packagesDir,
+          processRunner: processRunner, platform: mockPlatform);
+
+      runner = CommandRunner<void>(
+          'native_test_command', 'Test for native_test_command');
+      runner.addCommand(command);
+    });
+
+    test('fails if no platforms are provided', () async {
+      Error? commandError;
+      final List<String> output = await runCapturingPrint(
+          runner, <String>['native-test'], errorHandler: (Error e) {
+        commandError = e;
+      });
+
+      expect(commandError, isA<ToolExit>());
+      expect(
+        output,
+        containsAllInOrder(<Matcher>[
+          contains('At least one platform flag must be provided.'),
+        ]),
+      );
+    });
+
+    test('fails if all test types are disabled', () async {
+      Error? commandError;
+      final List<String> output = await runCapturingPrint(runner, <String>[
+        'native-test',
+        '--macos',
+        '--no-unit',
+        '--no-integration',
+      ], errorHandler: (Error e) {
+        commandError = e;
+      });
+
+      expect(commandError, isA<ToolExit>());
+      expect(
+        output,
+        containsAllInOrder(<Matcher>[
+          contains('At least one test type must be enabled.'),
+        ]),
+      );
+    });
+
+    test('reports skips with no tests', () async {
+      final Directory pluginDirectory1 = createFakePlugin('plugin', packagesDir,
+          platformSupport: <String, PlatformSupport>{
+            kPlatformMacos: PlatformSupport.inline,
+          });
+
+      final Directory pluginExampleDirectory =
+          pluginDirectory1.childDirectory('example');
+
+      // Exit code 66 from testing indicates no tests.
+      final MockProcess noTestsProcessResult = MockProcess();
+      noTestsProcessResult.exitCodeCompleter.complete(66);
+      processRunner.mockProcessesForExecutable['xcrun'] = <io.Process>[
+        noTestsProcessResult,
+      ];
+      final List<String> output =
+          await runCapturingPrint(runner, <String>['native-test', '--macos']);
+
+      expect(output, contains(contains('No tests found.')));
+
+      expect(
+          processRunner.recordedCalls,
+          orderedEquals(<ProcessCall>[
+            ProcessCall(
+                'xcrun',
+                const <String>[
+                  'xcodebuild',
+                  'test',
+                  '-workspace',
+                  'macos/Runner.xcworkspace',
+                  '-scheme',
+                  'Runner',
+                  '-configuration',
+                  'Debug',
+                  'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                ],
+                pluginExampleDirectory.path),
+          ]));
+    });
+
+    group('iOS', () {
+      test('skip if iOS is not supported', () async {
+        createFakePlugin('plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformMacos: PlatformSupport.inline,
+            });
+
+        final List<String> output = await runCapturingPrint(runner,
+            <String>['native-test', '--ios', _kDestination, 'foo_destination']);
+        expect(
+            output,
+            containsAllInOrder(<Matcher>[
+              contains('No implementation for iOS.'),
+              contains('SKIPPING: Not implemented for target platform(s).'),
+            ]));
+        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
+      });
+
+      test('skip if iOS is implemented in a federated package', () async {
+        createFakePlugin('plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformIos: PlatformSupport.federated
+            });
+
+        final List<String> output = await runCapturingPrint(runner,
+            <String>['native-test', '--ios', _kDestination, 'foo_destination']);
+        expect(
+            output,
+            containsAllInOrder(<Matcher>[
+              contains('No implementation for iOS.'),
+              contains('SKIPPING: Not implemented for target platform(s).'),
+            ]));
+        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
+      });
+
+      test('running with correct destination', () async {
+        final Directory pluginDirectory = createFakePlugin(
+            'plugin', packagesDir, platformSupport: <String, PlatformSupport>{
+          kPlatformIos: PlatformSupport.inline
+        });
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory.childDirectory('example');
+
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--ios',
+          _kDestination,
+          'foo_destination',
+        ]);
+
+        expect(
+            output,
+            containsAllInOrder(<Matcher>[
+              contains('Running for plugin'),
+              contains('Successfully ran iOS xctest for plugin/example')
+            ]));
+
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              ProcessCall(
+                  'xcrun',
+                  const <String>[
+                    'xcodebuild',
+                    'test',
+                    '-workspace',
+                    'ios/Runner.xcworkspace',
+                    '-scheme',
+                    'Runner',
+                    '-configuration',
+                    'Debug',
+                    '-destination',
+                    'foo_destination',
+                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                  ],
+                  pluginExampleDirectory.path),
+            ]));
+      });
+
+      test('Not specifying --ios-destination assigns an available simulator',
+          () async {
+        final Directory pluginDirectory = createFakePlugin(
+            'plugin', packagesDir, platformSupport: <String, PlatformSupport>{
+          kPlatformIos: PlatformSupport.inline
+        });
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory.childDirectory('example');
+
+        processRunner.processToReturn = MockProcess.succeeding();
+        processRunner.resultStdout = jsonEncode(_kDeviceListMap);
+        await runCapturingPrint(runner, <String>['native-test', '--ios']);
+
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              const ProcessCall(
+                  'xcrun',
+                  <String>[
+                    'simctl',
+                    'list',
+                    'devices',
+                    'runtimes',
+                    'available',
+                    '--json',
+                  ],
+                  null),
+              ProcessCall(
+                  'xcrun',
+                  const <String>[
+                    'xcodebuild',
+                    'test',
+                    '-workspace',
+                    'ios/Runner.xcworkspace',
+                    '-scheme',
+                    'Runner',
+                    '-configuration',
+                    'Debug',
+                    '-destination',
+                    'id=1E76A0FD-38AC-4537-A989-EA639D7D012A',
+                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                  ],
+                  pluginExampleDirectory.path),
+            ]));
+      });
+    });
+
+    group('macOS', () {
+      test('skip if macOS is not supported', () async {
+        createFakePlugin('plugin', packagesDir);
+
+        final List<String> output =
+            await runCapturingPrint(runner, <String>['native-test', '--macos']);
+
+        expect(
+            output,
+            containsAllInOrder(<Matcher>[
+              contains('No implementation for macOS.'),
+              contains('SKIPPING: Not implemented for target platform(s).'),
+            ]));
+        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
+      });
+
+      test('skip if macOS is implemented in a federated package', () async {
+        createFakePlugin('plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformMacos: PlatformSupport.federated,
+            });
+
+        final List<String> output =
+            await runCapturingPrint(runner, <String>['native-test', '--macos']);
+
+        expect(
+            output,
+            containsAllInOrder(<Matcher>[
+              contains('No implementation for macOS.'),
+              contains('SKIPPING: Not implemented for target platform(s).'),
+            ]));
+        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
+      });
+
+      test('runs for macOS plugin', () async {
+        final Directory pluginDirectory1 = createFakePlugin(
+            'plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformMacos: PlatformSupport.inline,
+            });
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory1.childDirectory('example');
+
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--macos',
+        ]);
+
+        expect(
+            output,
+            contains(
+                contains('Successfully ran macOS xctest for plugin/example')));
+
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              ProcessCall(
+                  'xcrun',
+                  const <String>[
+                    'xcodebuild',
+                    'test',
+                    '-workspace',
+                    'macos/Runner.xcworkspace',
+                    '-scheme',
+                    'Runner',
+                    '-configuration',
+                    'Debug',
+                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                  ],
+                  pluginExampleDirectory.path),
+            ]));
+      });
+    });
+
+    group('Android', () {
+      test('runs Java tests in Android implementation folder', () async {
+        final Directory plugin = createFakePlugin(
+          'plugin',
+          packagesDir,
+          platformSupport: <String, PlatformSupport>{
+            kPlatformAndroid: PlatformSupport.inline
+          },
+          extraFiles: <String>[
+            'example/android/gradlew',
+            'android/src/test/example_test.java',
+          ],
+        );
+
+        await runCapturingPrint(runner, <String>['native-test', '--android']);
+
+        final Directory androidFolder =
+            plugin.childDirectory('example').childDirectory('android');
+
+        expect(
+          processRunner.recordedCalls,
+          orderedEquals(<ProcessCall>[
+            ProcessCall(
+              androidFolder.childFile('gradlew').path,
+              const <String>['testDebugUnitTest', '--info'],
+              androidFolder.path,
+            ),
+          ]),
+        );
+      });
+
+      test('runs Java tests in example folder', () async {
+        final Directory plugin = createFakePlugin(
+          'plugin',
+          packagesDir,
+          platformSupport: <String, PlatformSupport>{
+            kPlatformAndroid: PlatformSupport.inline
+          },
+          extraFiles: <String>[
+            'example/android/gradlew',
+            'example/android/app/src/test/example_test.java',
+          ],
+        );
+
+        await runCapturingPrint(runner, <String>['native-test', '--android']);
+
+        final Directory androidFolder =
+            plugin.childDirectory('example').childDirectory('android');
+
+        expect(
+          processRunner.recordedCalls,
+          orderedEquals(<ProcessCall>[
+            ProcessCall(
+              androidFolder.childFile('gradlew').path,
+              const <String>['testDebugUnitTest', '--info'],
+              androidFolder.path,
+            ),
+          ]),
+        );
+      });
+
+      test('fails when the app needs to be built', () async {
+        createFakePlugin(
+          'plugin',
+          packagesDir,
+          platformSupport: <String, PlatformSupport>{
+            kPlatformAndroid: PlatformSupport.inline
+          },
+          extraFiles: <String>[
+            'example/android/app/src/test/example_test.java',
+          ],
+        );
+
+        Error? commandError;
+        final List<String> output = await runCapturingPrint(
+            runner, <String>['native-test', '--android'],
+            errorHandler: (Error e) {
+          commandError = e;
+        });
+
+        expect(commandError, isA<ToolExit>());
+
+        expect(
+          output,
+          containsAllInOrder(<Matcher>[
+            contains('ERROR: Run "flutter build apk" on plugin/example'),
+            contains('plugin:\n'
+                '    Examples must be built before testing.')
+          ]),
+        );
+      });
+
+      test('fails when a test fails', () async {
+        final Directory pluginDir = createFakePlugin(
+          'plugin',
+          packagesDir,
+          platformSupport: <String, PlatformSupport>{
+            kPlatformAndroid: PlatformSupport.inline
+          },
+          extraFiles: <String>[
+            'example/android/gradlew',
+            'example/android/app/src/test/example_test.java',
+          ],
+        );
+
+        final String gradlewPath = pluginDir
+            .childDirectory('example')
+            .childDirectory('android')
+            .childFile('gradlew')
+            .path;
+        processRunner.mockProcessesForExecutable[gradlewPath] = <io.Process>[
+          MockProcess.failing()
+        ];
+
+        Error? commandError;
+        final List<String> output = await runCapturingPrint(
+            runner, <String>['native-test', '--android'],
+            errorHandler: (Error e) {
+          commandError = e;
+        });
+
+        expect(commandError, isA<ToolExit>());
+
+        expect(
+          output,
+          containsAllInOrder(<Matcher>[
+            contains('plugin/example tests failed.'),
+            contains('The following packages had errors:'),
+            contains('plugin')
+          ]),
+        );
+      });
+
+      test('skips if Android is not supported', () async {
+        createFakePlugin(
+          'plugin',
+          packagesDir,
+        );
+
+        final List<String> output = await runCapturingPrint(
+            runner, <String>['native-test', '--android']);
+
+        expect(
+          output,
+          containsAllInOrder(<Matcher>[
+            contains('No implementation for Android.'),
+            contains('SKIPPING: Not implemented for target platform(s).'),
+          ]),
+        );
+      });
+
+      test('skips when running no tests', () async {
+        createFakePlugin(
+          'plugin',
+          packagesDir,
+          platformSupport: <String, PlatformSupport>{
+            kPlatformAndroid: PlatformSupport.inline
+          },
+        );
+
+        final List<String> output = await runCapturingPrint(
+            runner, <String>['native-test', '--android']);
+
+        expect(
+          output,
+          containsAllInOrder(<Matcher>[
+            contains('No Android tests found for plugin/example'),
+            contains('SKIPPING: No tests found.'),
+          ]),
+        );
+      });
+    });
+
+    // Tests behaviors of implementation that is shared between iOS and macOS.
+    group('iOS/macOS', () {
+      test('fails if xcrun fails', () async {
+        createFakePlugin('plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformMacos: PlatformSupport.inline,
+            });
+
+        processRunner.mockProcessesForExecutable['xcrun'] = <io.Process>[
+          MockProcess.failing()
+        ];
+
+        Error? commandError;
+        final List<String> output =
+            await runCapturingPrint(runner, <String>['native-test', '--macos'],
+                errorHandler: (Error e) {
+          commandError = e;
+        });
+
+        expect(commandError, isA<ToolExit>());
+        expect(
+          output,
+          containsAllInOrder(<Matcher>[
+            contains('The following packages had errors:'),
+            contains('  plugin'),
+          ]),
+        );
+      });
+
+      test('honors unit-only', () async {
+        final Directory pluginDirectory1 = createFakePlugin(
+            'plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformMacos: PlatformSupport.inline,
+            });
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory1.childDirectory('example');
+
+        processRunner.processToReturn = MockProcess.succeeding();
+        processRunner.resultStdout =
+            '{"project":{"targets":["RunnerTests", "RunnerUITests"]}}';
+
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--macos',
+          '--no-integration',
+        ]);
+
+        expect(
+            output,
+            contains(
+                contains('Successfully ran macOS xctest for plugin/example')));
+
+        // --no-integration should translate to '-only-testing:RunnerTests'.
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              ProcessCall(
+                  'xcrun',
+                  <String>[
+                    'xcodebuild',
+                    '-list',
+                    '-json',
+                    '-project',
+                    pluginExampleDirectory
+                        .childDirectory('macos')
+                        .childDirectory('Runner.xcodeproj')
+                        .path,
+                  ],
+                  null),
+              ProcessCall(
+                  'xcrun',
+                  const <String>[
+                    'xcodebuild',
+                    'test',
+                    '-workspace',
+                    'macos/Runner.xcworkspace',
+                    '-scheme',
+                    'Runner',
+                    '-configuration',
+                    'Debug',
+                    '-only-testing:RunnerTests',
+                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                  ],
+                  pluginExampleDirectory.path),
+            ]));
+      });
+
+      test('honors integration-only', () async {
+        final Directory pluginDirectory1 = createFakePlugin(
+            'plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformMacos: PlatformSupport.inline,
+            });
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory1.childDirectory('example');
+
+        processRunner.processToReturn = MockProcess.succeeding();
+        processRunner.resultStdout =
+            '{"project":{"targets":["RunnerTests", "RunnerUITests"]}}';
+
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--macos',
+          '--no-unit',
+        ]);
+
+        expect(
+            output,
+            contains(
+                contains('Successfully ran macOS xctest for plugin/example')));
+
+        // --no-unit should translate to '-only-testing:RunnerUITests'.
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              ProcessCall(
+                  'xcrun',
+                  <String>[
+                    'xcodebuild',
+                    '-list',
+                    '-json',
+                    '-project',
+                    pluginExampleDirectory
+                        .childDirectory('macos')
+                        .childDirectory('Runner.xcodeproj')
+                        .path,
+                  ],
+                  null),
+              ProcessCall(
+                  'xcrun',
+                  const <String>[
+                    'xcodebuild',
+                    'test',
+                    '-workspace',
+                    'macos/Runner.xcworkspace',
+                    '-scheme',
+                    'Runner',
+                    '-configuration',
+                    'Debug',
+                    '-only-testing:RunnerUITests',
+                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                  ],
+                  pluginExampleDirectory.path),
+            ]));
+      });
+
+      test('skips when the requested target is not present', () async {
+        final Directory pluginDirectory1 = createFakePlugin(
+            'plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformMacos: PlatformSupport.inline,
+            });
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory1.childDirectory('example');
+
+        processRunner.processToReturn = MockProcess.succeeding();
+        // Simulate a project with unit tests but no integration tests...
+        processRunner.resultStdout = '{"project":{"targets":["RunnerTests"]}}';
+        // ... then try to run only integration tests.
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--macos',
+          '--no-unit',
+        ]);
+
+        expect(
+            output,
+            containsAllInOrder(<Matcher>[
+              contains(
+                  'No "RunnerUITests" target in plugin/example; skipping.'),
+            ]));
+
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              ProcessCall(
+                  'xcrun',
+                  <String>[
+                    'xcodebuild',
+                    '-list',
+                    '-json',
+                    '-project',
+                    pluginExampleDirectory
+                        .childDirectory('macos')
+                        .childDirectory('Runner.xcodeproj')
+                        .path,
+                  ],
+                  null),
+            ]));
+      });
+
+      test('fails if unable to check for requested target', () async {
+        final Directory pluginDirectory1 = createFakePlugin(
+            'plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformMacos: PlatformSupport.inline,
+            });
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory1.childDirectory('example');
+
+        processRunner.processToReturn = MockProcess.failing();
+
+        Error? commandError;
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--macos',
+          '--no-integration',
+        ], errorHandler: (Error e) {
+          commandError = e;
+        });
+
+        expect(commandError, isA<ToolExit>());
+        expect(
+          output,
+          containsAllInOrder(<Matcher>[
+            contains('Unable to check targets for plugin/example.'),
+          ]),
+        );
+
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              ProcessCall(
+                  'xcrun',
+                  <String>[
+                    'xcodebuild',
+                    '-list',
+                    '-json',
+                    '-project',
+                    pluginExampleDirectory
+                        .childDirectory('macos')
+                        .childDirectory('Runner.xcodeproj')
+                        .path,
+                  ],
+                  null),
+            ]));
+      });
+    });
+
+    group('multiplatform', () {
+      test('runs all platfroms when supported', () async {
+        final Directory pluginDirectory = createFakePlugin(
+          'plugin',
+          packagesDir,
+          extraFiles: <String>[
+            'example/android/gradlew',
+            'android/src/test/example_test.java',
+          ],
+          platformSupport: <String, PlatformSupport>{
+            kPlatformAndroid: PlatformSupport.inline,
+            kPlatformIos: PlatformSupport.inline,
+            kPlatformMacos: PlatformSupport.inline,
+          },
+        );
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory.childDirectory('example');
+        final Directory androidFolder =
+            pluginExampleDirectory.childDirectory('android');
+
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--android',
+          '--ios',
+          '--macos',
+          _kDestination,
+          'foo_destination',
+        ]);
+
+        expect(
+            output,
+            containsAll(<Matcher>[
+              contains('Running Android tests for plugin/example'),
+              contains('Successfully ran iOS xctest for plugin/example'),
+              contains('Successfully ran macOS xctest for plugin/example'),
+            ]));
+
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              ProcessCall(
+                  androidFolder.childFile('gradlew').path,
+                  const <String>['testDebugUnitTest', '--info'],
+                  androidFolder.path),
+              ProcessCall(
+                  'xcrun',
+                  const <String>[
+                    'xcodebuild',
+                    'test',
+                    '-workspace',
+                    'ios/Runner.xcworkspace',
+                    '-scheme',
+                    'Runner',
+                    '-configuration',
+                    'Debug',
+                    '-destination',
+                    'foo_destination',
+                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                  ],
+                  pluginExampleDirectory.path),
+              ProcessCall(
+                  'xcrun',
+                  const <String>[
+                    'xcodebuild',
+                    'test',
+                    '-workspace',
+                    'macos/Runner.xcworkspace',
+                    '-scheme',
+                    'Runner',
+                    '-configuration',
+                    'Debug',
+                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                  ],
+                  pluginExampleDirectory.path),
+            ]));
+      });
+
+      test('runs only macOS for a macOS plugin', () async {
+        final Directory pluginDirectory1 = createFakePlugin(
+            'plugin', packagesDir,
+            platformSupport: <String, PlatformSupport>{
+              kPlatformMacos: PlatformSupport.inline,
+            });
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory1.childDirectory('example');
+
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--ios',
+          '--macos',
+          _kDestination,
+          'foo_destination',
+        ]);
+
+        expect(
+            output,
+            containsAllInOrder(<Matcher>[
+              contains('No implementation for iOS.'),
+              contains('Successfully ran macOS xctest for plugin/example'),
+            ]));
+
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              ProcessCall(
+                  'xcrun',
+                  const <String>[
+                    'xcodebuild',
+                    'test',
+                    '-workspace',
+                    'macos/Runner.xcworkspace',
+                    '-scheme',
+                    'Runner',
+                    '-configuration',
+                    'Debug',
+                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                  ],
+                  pluginExampleDirectory.path),
+            ]));
+      });
+
+      test('runs only iOS for a iOS plugin', () async {
+        final Directory pluginDirectory = createFakePlugin(
+            'plugin', packagesDir, platformSupport: <String, PlatformSupport>{
+          kPlatformIos: PlatformSupport.inline
+        });
+
+        final Directory pluginExampleDirectory =
+            pluginDirectory.childDirectory('example');
+
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--ios',
+          '--macos',
+          _kDestination,
+          'foo_destination',
+        ]);
+
+        expect(
+            output,
+            containsAllInOrder(<Matcher>[
+              contains('No implementation for macOS.'),
+              contains('Successfully ran iOS xctest for plugin/example')
+            ]));
+
+        expect(
+            processRunner.recordedCalls,
+            orderedEquals(<ProcessCall>[
+              ProcessCall(
+                  'xcrun',
+                  const <String>[
+                    'xcodebuild',
+                    'test',
+                    '-workspace',
+                    'ios/Runner.xcworkspace',
+                    '-scheme',
+                    'Runner',
+                    '-configuration',
+                    'Debug',
+                    '-destination',
+                    'foo_destination',
+                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
+                  ],
+                  pluginExampleDirectory.path),
+            ]));
+      });
+
+      test('skips when nothing is supported', () async {
+        createFakePlugin('plugin', packagesDir);
+
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--android',
+          '--ios',
+          '--macos',
+          _kDestination,
+          'foo_destination',
+        ]);
+
+        expect(
+            output,
+            containsAllInOrder(<Matcher>[
+              contains('No implementation for Android.'),
+              contains('No implementation for iOS.'),
+              contains('No implementation for macOS.'),
+              contains('SKIPPING: Not implemented for target platform(s).'),
+            ]));
+
+        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
+      });
+
+      test('failing one platform does not stop the tests', () async {
+        final Directory pluginDir = createFakePlugin(
+          'plugin',
+          packagesDir,
+          platformSupport: <String, PlatformSupport>{
+            kPlatformAndroid: PlatformSupport.inline,
+            kPlatformIos: PlatformSupport.inline,
+          },
+          extraFiles: <String>[
+            'example/android/gradlew',
+            'example/android/app/src/test/example_test.java',
+          ],
+        );
+
+        // Simulate failing Android, but not iOS.
+        final String gradlewPath = pluginDir
+            .childDirectory('example')
+            .childDirectory('android')
+            .childFile('gradlew')
+            .path;
+        processRunner.mockProcessesForExecutable[gradlewPath] = <io.Process>[
+          MockProcess.failing()
+        ];
+
+        Error? commandError;
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--android',
+          '--ios',
+          '--ios-destination',
+          'foo_destination',
+        ], errorHandler: (Error e) {
+          commandError = e;
+        });
+
+        expect(commandError, isA<ToolExit>());
+
+        expect(
+          output,
+          containsAllInOrder(<Matcher>[
+            contains('Running tests for Android...'),
+            contains('plugin/example tests failed.'),
+            contains('Running tests for iOS...'),
+            contains('Successfully ran iOS xctest for plugin/example'),
+            contains('The following packages had errors:'),
+            contains('plugin:\n'
+                '    Android')
+          ]),
+        );
+      });
+
+      test('failing multiple platforms reports multiple failures', () async {
+        final Directory pluginDir = createFakePlugin(
+          'plugin',
+          packagesDir,
+          platformSupport: <String, PlatformSupport>{
+            kPlatformAndroid: PlatformSupport.inline,
+            kPlatformIos: PlatformSupport.inline,
+          },
+          extraFiles: <String>[
+            'example/android/gradlew',
+            'example/android/app/src/test/example_test.java',
+          ],
+        );
+
+        // Simulate failing Android.
+        final String gradlewPath = pluginDir
+            .childDirectory('example')
+            .childDirectory('android')
+            .childFile('gradlew')
+            .path;
+        processRunner.mockProcessesForExecutable[gradlewPath] = <io.Process>[
+          MockProcess.failing()
+        ];
+        // Simulate failing Android.
+        processRunner.mockProcessesForExecutable['xcrun'] = <io.Process>[
+          MockProcess.failing()
+        ];
+
+        Error? commandError;
+        final List<String> output = await runCapturingPrint(runner, <String>[
+          'native-test',
+          '--android',
+          '--ios',
+          '--ios-destination',
+          'foo_destination',
+        ], errorHandler: (Error e) {
+          commandError = e;
+        });
+
+        expect(commandError, isA<ToolExit>());
+
+        expect(
+          output,
+          containsAllInOrder(<Matcher>[
+            contains('Running tests for Android...'),
+            contains('Running tests for iOS...'),
+            contains('The following packages had errors:'),
+            contains('plugin:\n'
+                '    Android\n'
+                '    iOS')
+          ]),
+        );
+      });
+    });
+  });
+}
diff --git a/script/tool/test/xctest_command_test.dart b/script/tool/test/xctest_command_test.dart
deleted file mode 100644
index 324dea0..0000000
--- a/script/tool/test/xctest_command_test.dart
+++ /dev/null
@@ -1,705 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:io' as io;
-
-import 'package:args/command_runner.dart';
-import 'package:file/file.dart';
-import 'package:file/memory.dart';
-import 'package:flutter_plugin_tools/src/common/core.dart';
-import 'package:flutter_plugin_tools/src/common/plugin_utils.dart';
-import 'package:flutter_plugin_tools/src/xctest_command.dart';
-import 'package:test/test.dart';
-
-import 'mocks.dart';
-import 'util.dart';
-
-final Map<String, dynamic> _kDeviceListMap = <String, dynamic>{
-  'runtimes': <Map<String, dynamic>>[
-    <String, dynamic>{
-      'bundlePath':
-          '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime',
-      'buildversion': '17L255',
-      'runtimeRoot':
-          '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime/Contents/Resources/RuntimeRoot',
-      'identifier': 'com.apple.CoreSimulator.SimRuntime.iOS-13-4',
-      'version': '13.4',
-      'isAvailable': true,
-      'name': 'iOS 13.4'
-    },
-  ],
-  'devices': <String, dynamic>{
-    'com.apple.CoreSimulator.SimRuntime.iOS-13-4': <Map<String, dynamic>>[
-      <String, dynamic>{
-        'dataPath':
-            '/Users/xxx/Library/Developer/CoreSimulator/Devices/1E76A0FD-38AC-4537-A989-EA639D7D012A/data',
-        'logPath':
-            '/Users/xxx/Library/Logs/CoreSimulator/1E76A0FD-38AC-4537-A989-EA639D7D012A',
-        'udid': '1E76A0FD-38AC-4537-A989-EA639D7D012A',
-        'isAvailable': true,
-        'deviceTypeIdentifier':
-            'com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus',
-        'state': 'Shutdown',
-        'name': 'iPhone 8 Plus'
-      }
-    ]
-  }
-};
-
-// TODO(stuartmorgan): Rework these tests to use a mock Xcode instead of
-// doing all the process mocking and validation.
-void main() {
-  const String _kDestination = '--ios-destination';
-
-  group('test xctest_command', () {
-    late FileSystem fileSystem;
-    late MockPlatform mockPlatform;
-    late Directory packagesDir;
-    late CommandRunner<void> runner;
-    late RecordingProcessRunner processRunner;
-
-    setUp(() {
-      fileSystem = MemoryFileSystem();
-      mockPlatform = MockPlatform(isMacOS: true);
-      packagesDir = createPackagesDirectory(fileSystem: fileSystem);
-      processRunner = RecordingProcessRunner();
-      final XCTestCommand command = XCTestCommand(packagesDir,
-          processRunner: processRunner, platform: mockPlatform);
-
-      runner = CommandRunner<void>('xctest_command', 'Test for xctest_command');
-      runner.addCommand(command);
-    });
-
-    test('Fails if no platforms are provided', () async {
-      Error? commandError;
-      final List<String> output = await runCapturingPrint(
-          runner, <String>['xctest'], errorHandler: (Error e) {
-        commandError = e;
-      });
-
-      expect(commandError, isA<ToolExit>());
-      expect(
-        output,
-        containsAllInOrder(<Matcher>[
-          contains('At least one platform flag must be provided'),
-        ]),
-      );
-    });
-
-    test('allows target filtering', () async {
-      final Directory pluginDirectory1 = createFakePlugin('plugin', packagesDir,
-          platformSupport: <String, PlatformSupport>{
-            kPlatformMacos: PlatformSupport.inline,
-          });
-
-      final Directory pluginExampleDirectory =
-          pluginDirectory1.childDirectory('example');
-
-      processRunner.processToReturn = MockProcess.succeeding();
-      processRunner.resultStdout = '{"project":{"targets":["RunnerTests"]}}';
-
-      final List<String> output = await runCapturingPrint(runner, <String>[
-        'xctest',
-        '--macos',
-        '--test-target=RunnerTests',
-      ]);
-
-      expect(
-          output,
-          contains(
-              contains('Successfully ran macOS xctest for plugin/example')));
-
-      expect(
-          processRunner.recordedCalls,
-          orderedEquals(<ProcessCall>[
-            ProcessCall(
-                'xcrun',
-                <String>[
-                  'xcodebuild',
-                  '-list',
-                  '-json',
-                  '-project',
-                  pluginExampleDirectory
-                      .childDirectory('macos')
-                      .childDirectory('Runner.xcodeproj')
-                      .path,
-                ],
-                null),
-            ProcessCall(
-                'xcrun',
-                const <String>[
-                  'xcodebuild',
-                  'test',
-                  '-workspace',
-                  'macos/Runner.xcworkspace',
-                  '-scheme',
-                  'Runner',
-                  '-configuration',
-                  'Debug',
-                  '-only-testing:RunnerTests',
-                  'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-                ],
-                pluginExampleDirectory.path),
-          ]));
-    });
-
-    test('skips when the requested target is not present', () async {
-      final Directory pluginDirectory1 = createFakePlugin('plugin', packagesDir,
-          platformSupport: <String, PlatformSupport>{
-            kPlatformMacos: PlatformSupport.inline,
-          });
-
-      final Directory pluginExampleDirectory =
-          pluginDirectory1.childDirectory('example');
-
-      processRunner.processToReturn = MockProcess.succeeding();
-      processRunner.resultStdout = '{"project":{"targets":["Runner"]}}';
-      final List<String> output = await runCapturingPrint(runner, <String>[
-        'xctest',
-        '--macos',
-        '--test-target=RunnerTests',
-      ]);
-
-      expect(
-          output,
-          containsAllInOrder(<Matcher>[
-            contains('No "RunnerTests" target in plugin/example; skipping.'),
-          ]));
-
-      expect(
-          processRunner.recordedCalls,
-          orderedEquals(<ProcessCall>[
-            ProcessCall(
-                'xcrun',
-                <String>[
-                  'xcodebuild',
-                  '-list',
-                  '-json',
-                  '-project',
-                  pluginExampleDirectory
-                      .childDirectory('macos')
-                      .childDirectory('Runner.xcodeproj')
-                      .path,
-                ],
-                null),
-          ]));
-    });
-
-    test('fails if unable to check for requested target', () async {
-      final Directory pluginDirectory1 = createFakePlugin('plugin', packagesDir,
-          platformSupport: <String, PlatformSupport>{
-            kPlatformMacos: PlatformSupport.inline,
-          });
-
-      final Directory pluginExampleDirectory =
-          pluginDirectory1.childDirectory('example');
-
-      processRunner.processToReturn = MockProcess.failing();
-
-      Error? commandError;
-      final List<String> output = await runCapturingPrint(runner, <String>[
-        'xctest',
-        '--macos',
-        '--test-target=RunnerTests',
-      ], errorHandler: (Error e) {
-        commandError = e;
-      });
-
-      expect(commandError, isA<ToolExit>());
-      expect(
-        output,
-        containsAllInOrder(<Matcher>[
-          contains('Unable to check targets for plugin/example.'),
-        ]),
-      );
-
-      expect(
-          processRunner.recordedCalls,
-          orderedEquals(<ProcessCall>[
-            ProcessCall(
-                'xcrun',
-                <String>[
-                  'xcodebuild',
-                  '-list',
-                  '-json',
-                  '-project',
-                  pluginExampleDirectory
-                      .childDirectory('macos')
-                      .childDirectory('Runner.xcodeproj')
-                      .path,
-                ],
-                null),
-          ]));
-    });
-
-    test('reports skips with no tests', () async {
-      final Directory pluginDirectory1 = createFakePlugin('plugin', packagesDir,
-          platformSupport: <String, PlatformSupport>{
-            kPlatformMacos: PlatformSupport.inline,
-          });
-
-      final Directory pluginExampleDirectory =
-          pluginDirectory1.childDirectory('example');
-
-      // Exit code 66 from testing indicates no tests.
-      final MockProcess noTestsProcessResult = MockProcess();
-      noTestsProcessResult.exitCodeCompleter.complete(66);
-      processRunner.mockProcessesForExecutable['xcrun'] = <io.Process>[
-        noTestsProcessResult,
-      ];
-      final List<String> output =
-          await runCapturingPrint(runner, <String>['xctest', '--macos']);
-
-      expect(output, contains(contains('No tests found.')));
-
-      expect(
-          processRunner.recordedCalls,
-          orderedEquals(<ProcessCall>[
-            ProcessCall(
-                'xcrun',
-                const <String>[
-                  'xcodebuild',
-                  'test',
-                  '-workspace',
-                  'macos/Runner.xcworkspace',
-                  '-scheme',
-                  'Runner',
-                  '-configuration',
-                  'Debug',
-                  'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-                ],
-                pluginExampleDirectory.path),
-          ]));
-    });
-
-    group('iOS', () {
-      test('skip if iOS is not supported', () async {
-        createFakePlugin('plugin', packagesDir,
-            platformSupport: <String, PlatformSupport>{
-              kPlatformMacos: PlatformSupport.inline,
-            });
-
-        final List<String> output = await runCapturingPrint(runner,
-            <String>['xctest', '--ios', _kDestination, 'foo_destination']);
-        expect(
-            output,
-            contains(
-                contains('iOS is not implemented by this plugin package.')));
-        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
-      });
-
-      test('skip if iOS is implemented in a federated package', () async {
-        createFakePlugin('plugin', packagesDir,
-            platformSupport: <String, PlatformSupport>{
-              kPlatformIos: PlatformSupport.federated
-            });
-
-        final List<String> output = await runCapturingPrint(runner,
-            <String>['xctest', '--ios', _kDestination, 'foo_destination']);
-        expect(
-            output,
-            contains(
-                contains('iOS is not implemented by this plugin package.')));
-        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
-      });
-
-      test('running with correct destination', () async {
-        final Directory pluginDirectory = createFakePlugin(
-            'plugin', packagesDir, platformSupport: <String, PlatformSupport>{
-          kPlatformIos: PlatformSupport.inline
-        });
-
-        final Directory pluginExampleDirectory =
-            pluginDirectory.childDirectory('example');
-
-        final List<String> output = await runCapturingPrint(runner, <String>[
-          'xctest',
-          '--ios',
-          _kDestination,
-          'foo_destination',
-        ]);
-
-        expect(
-            output,
-            containsAllInOrder(<Matcher>[
-              contains('Running for plugin'),
-              contains('Successfully ran iOS xctest for plugin/example')
-            ]));
-
-        expect(
-            processRunner.recordedCalls,
-            orderedEquals(<ProcessCall>[
-              ProcessCall(
-                  'xcrun',
-                  const <String>[
-                    'xcodebuild',
-                    'test',
-                    '-workspace',
-                    'ios/Runner.xcworkspace',
-                    '-scheme',
-                    'Runner',
-                    '-configuration',
-                    'Debug',
-                    '-destination',
-                    'foo_destination',
-                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-                  ],
-                  pluginExampleDirectory.path),
-            ]));
-      });
-
-      test('Not specifying --ios-destination assigns an available simulator',
-          () async {
-        final Directory pluginDirectory = createFakePlugin(
-            'plugin', packagesDir, platformSupport: <String, PlatformSupport>{
-          kPlatformIos: PlatformSupport.inline
-        });
-
-        final Directory pluginExampleDirectory =
-            pluginDirectory.childDirectory('example');
-
-        processRunner.processToReturn = MockProcess.succeeding();
-        processRunner.resultStdout = jsonEncode(_kDeviceListMap);
-        await runCapturingPrint(runner, <String>['xctest', '--ios']);
-
-        expect(
-            processRunner.recordedCalls,
-            orderedEquals(<ProcessCall>[
-              const ProcessCall(
-                  'xcrun',
-                  <String>[
-                    'simctl',
-                    'list',
-                    'devices',
-                    'runtimes',
-                    'available',
-                    '--json',
-                  ],
-                  null),
-              ProcessCall(
-                  'xcrun',
-                  const <String>[
-                    'xcodebuild',
-                    'test',
-                    '-workspace',
-                    'ios/Runner.xcworkspace',
-                    '-scheme',
-                    'Runner',
-                    '-configuration',
-                    'Debug',
-                    '-destination',
-                    'id=1E76A0FD-38AC-4537-A989-EA639D7D012A',
-                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-                  ],
-                  pluginExampleDirectory.path),
-            ]));
-      });
-
-      test('fails if xcrun fails', () async {
-        createFakePlugin('plugin', packagesDir,
-            platformSupport: <String, PlatformSupport>{
-              kPlatformIos: PlatformSupport.inline
-            });
-
-        processRunner.mockProcessesForExecutable['xcrun'] = <io.Process>[
-          MockProcess.failing()
-        ];
-
-        Error? commandError;
-        final List<String> output = await runCapturingPrint(
-          runner,
-          <String>[
-            'xctest',
-            '--ios',
-            _kDestination,
-            'foo_destination',
-          ],
-          errorHandler: (Error e) {
-            commandError = e;
-          },
-        );
-
-        expect(commandError, isA<ToolExit>());
-        expect(
-            output,
-            containsAllInOrder(<Matcher>[
-              contains('The following packages had errors:'),
-              contains('  plugin'),
-            ]));
-      });
-    });
-
-    group('macOS', () {
-      test('skip if macOS is not supported', () async {
-        createFakePlugin('plugin', packagesDir);
-
-        final List<String> output =
-            await runCapturingPrint(runner, <String>['xctest', '--macos']);
-        expect(
-            output,
-            contains(
-                contains('macOS is not implemented by this plugin package.')));
-        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
-      });
-
-      test('skip if macOS is implemented in a federated package', () async {
-        createFakePlugin('plugin', packagesDir,
-            platformSupport: <String, PlatformSupport>{
-              kPlatformMacos: PlatformSupport.federated,
-            });
-
-        final List<String> output =
-            await runCapturingPrint(runner, <String>['xctest', '--macos']);
-        expect(
-            output,
-            contains(
-                contains('macOS is not implemented by this plugin package.')));
-        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
-      });
-
-      test('runs for macOS plugin', () async {
-        final Directory pluginDirectory1 = createFakePlugin(
-            'plugin', packagesDir,
-            platformSupport: <String, PlatformSupport>{
-              kPlatformMacos: PlatformSupport.inline,
-            });
-
-        final Directory pluginExampleDirectory =
-            pluginDirectory1.childDirectory('example');
-
-        final List<String> output = await runCapturingPrint(runner, <String>[
-          'xctest',
-          '--macos',
-        ]);
-
-        expect(
-            output,
-            contains(
-                contains('Successfully ran macOS xctest for plugin/example')));
-
-        expect(
-            processRunner.recordedCalls,
-            orderedEquals(<ProcessCall>[
-              ProcessCall(
-                  'xcrun',
-                  const <String>[
-                    'xcodebuild',
-                    'test',
-                    '-workspace',
-                    'macos/Runner.xcworkspace',
-                    '-scheme',
-                    'Runner',
-                    '-configuration',
-                    'Debug',
-                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-                  ],
-                  pluginExampleDirectory.path),
-            ]));
-      });
-
-      test('fails if xcrun fails', () async {
-        createFakePlugin('plugin', packagesDir,
-            platformSupport: <String, PlatformSupport>{
-              kPlatformMacos: PlatformSupport.inline,
-            });
-
-        processRunner.mockProcessesForExecutable['xcrun'] = <io.Process>[
-          MockProcess.failing()
-        ];
-
-        Error? commandError;
-        final List<String> output = await runCapturingPrint(
-            runner, <String>['xctest', '--macos'], errorHandler: (Error e) {
-          commandError = e;
-        });
-
-        expect(commandError, isA<ToolExit>());
-        expect(
-          output,
-          containsAllInOrder(<Matcher>[
-            contains('The following packages had errors:'),
-            contains('  plugin'),
-          ]),
-        );
-      });
-    });
-
-    group('combined', () {
-      test('runs both iOS and macOS when supported', () async {
-        final Directory pluginDirectory1 = createFakePlugin(
-            'plugin', packagesDir,
-            platformSupport: <String, PlatformSupport>{
-              kPlatformIos: PlatformSupport.inline,
-              kPlatformMacos: PlatformSupport.inline,
-            });
-
-        final Directory pluginExampleDirectory =
-            pluginDirectory1.childDirectory('example');
-
-        final List<String> output = await runCapturingPrint(runner, <String>[
-          'xctest',
-          '--ios',
-          '--macos',
-          _kDestination,
-          'foo_destination',
-        ]);
-
-        expect(
-            output,
-            containsAll(<Matcher>[
-              contains('Successfully ran iOS xctest for plugin/example'),
-              contains('Successfully ran macOS xctest for plugin/example'),
-            ]));
-
-        expect(
-            processRunner.recordedCalls,
-            orderedEquals(<ProcessCall>[
-              ProcessCall(
-                  'xcrun',
-                  const <String>[
-                    'xcodebuild',
-                    'test',
-                    '-workspace',
-                    'ios/Runner.xcworkspace',
-                    '-scheme',
-                    'Runner',
-                    '-configuration',
-                    'Debug',
-                    '-destination',
-                    'foo_destination',
-                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-                  ],
-                  pluginExampleDirectory.path),
-              ProcessCall(
-                  'xcrun',
-                  const <String>[
-                    'xcodebuild',
-                    'test',
-                    '-workspace',
-                    'macos/Runner.xcworkspace',
-                    '-scheme',
-                    'Runner',
-                    '-configuration',
-                    'Debug',
-                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-                  ],
-                  pluginExampleDirectory.path),
-            ]));
-      });
-
-      test('runs only macOS for a macOS plugin', () async {
-        final Directory pluginDirectory1 = createFakePlugin(
-            'plugin', packagesDir,
-            platformSupport: <String, PlatformSupport>{
-              kPlatformMacos: PlatformSupport.inline,
-            });
-
-        final Directory pluginExampleDirectory =
-            pluginDirectory1.childDirectory('example');
-
-        final List<String> output = await runCapturingPrint(runner, <String>[
-          'xctest',
-          '--ios',
-          '--macos',
-          _kDestination,
-          'foo_destination',
-        ]);
-
-        expect(
-            output,
-            containsAllInOrder(<Matcher>[
-              contains('Only running for macOS'),
-              contains('Successfully ran macOS xctest for plugin/example'),
-            ]));
-
-        expect(
-            processRunner.recordedCalls,
-            orderedEquals(<ProcessCall>[
-              ProcessCall(
-                  'xcrun',
-                  const <String>[
-                    'xcodebuild',
-                    'test',
-                    '-workspace',
-                    'macos/Runner.xcworkspace',
-                    '-scheme',
-                    'Runner',
-                    '-configuration',
-                    'Debug',
-                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-                  ],
-                  pluginExampleDirectory.path),
-            ]));
-      });
-
-      test('runs only iOS for a iOS plugin', () async {
-        final Directory pluginDirectory = createFakePlugin(
-            'plugin', packagesDir, platformSupport: <String, PlatformSupport>{
-          kPlatformIos: PlatformSupport.inline
-        });
-
-        final Directory pluginExampleDirectory =
-            pluginDirectory.childDirectory('example');
-
-        final List<String> output = await runCapturingPrint(runner, <String>[
-          'xctest',
-          '--ios',
-          '--macos',
-          _kDestination,
-          'foo_destination',
-        ]);
-
-        expect(
-            output,
-            containsAllInOrder(<Matcher>[
-              contains('Only running for iOS'),
-              contains('Successfully ran iOS xctest for plugin/example')
-            ]));
-
-        expect(
-            processRunner.recordedCalls,
-            orderedEquals(<ProcessCall>[
-              ProcessCall(
-                  'xcrun',
-                  const <String>[
-                    'xcodebuild',
-                    'test',
-                    '-workspace',
-                    'ios/Runner.xcworkspace',
-                    '-scheme',
-                    'Runner',
-                    '-configuration',
-                    'Debug',
-                    '-destination',
-                    'foo_destination',
-                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
-                  ],
-                  pluginExampleDirectory.path),
-            ]));
-      });
-
-      test('skips when neither are supported', () async {
-        createFakePlugin('plugin', packagesDir);
-
-        final List<String> output = await runCapturingPrint(runner, <String>[
-          'xctest',
-          '--ios',
-          '--macos',
-          _kDestination,
-          'foo_destination',
-        ]);
-
-        expect(
-            output,
-            containsAllInOrder(<Matcher>[
-              contains(
-                  'SKIPPING: Neither iOS nor macOS is implemented by this plugin package.'),
-            ]));
-
-        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
-      });
-    });
-  });
-}
