[pigeon] Consolidate platform test harnesses part 5 - macOS (#2813)

* Replace macOS test with a new, similar test using the shared structure

* Shared constant

* Analysis fix
diff --git a/packages/pigeon/platform_tests/macos_swift_unit_tests/macos/Classes/MacosSwiftUnitTestsPlugin.swift b/packages/pigeon/platform_tests/macos_swift_unit_tests/macos/Classes/MacosSwiftUnitTestsPlugin.swift
deleted file mode 100644
index 640df72..0000000
--- a/packages/pigeon/platform_tests/macos_swift_unit_tests/macos/Classes/MacosSwiftUnitTestsPlugin.swift
+++ /dev/null
@@ -1,19 +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 Cocoa
-import FlutterMacOS
-
-public class MyApi: Api {
-  public init() {}
-  func getPlatform() -> String {
-    return "macOS " + ProcessInfo.processInfo.operatingSystemVersionString
-  }
-}
-
-public class MacosSwiftUnitTestsPlugin: NSObject, FlutterPlugin {
-  public static func register(with registrar: FlutterPluginRegistrar) {
-    ApiSetup.setUp(binaryMessenger: registrar.messenger, api: MyApi())
-  }
-}
diff --git a/packages/pigeon/platform_tests/macos_swift_unit_tests/macos/Tests/MessagesTest.swift b/packages/pigeon/platform_tests/macos_swift_unit_tests/macos/Tests/MessagesTest.swift
deleted file mode 100644
index d877c0b..0000000
--- a/packages/pigeon/platform_tests/macos_swift_unit_tests/macos/Tests/MessagesTest.swift
+++ /dev/null
@@ -1,13 +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 XCTest
-import macos_swift_unit_tests
-
-class MessagesTest: XCTestCase {
-   func testMakeApi() {
-    let api = MyApi()
-    XCTAssertNotNil(api)
-   }
-}
diff --git a/packages/pigeon/platform_tests/macos_swift_unit_tests/macos/macos_swift_unit_tests.podspec b/packages/pigeon/platform_tests/macos_swift_unit_tests/macos/macos_swift_unit_tests.podspec
deleted file mode 100644
index bfecf1f..0000000
--- a/packages/pigeon/platform_tests/macos_swift_unit_tests/macos/macos_swift_unit_tests.podspec
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
-# Run `pod lib lint macos_swift_unit_tests.podspec` to validate before publishing.
-#
-Pod::Spec.new do |s|
-  s.name             = 'macos_swift_unit_tests'
-  s.version          = '0.0.1'
-  s.summary          = 'Fake library that uses pigeon for macos for testing.'
-  s.description      = <<-DESC
-Fake library that uses pigeon for macos for testing.
-
-Use `pod lib lint` to run the tests.
-                       DESC
-  s.homepage         = 'http://example.com'
-  s.license          = { :type => 'Flutter', :file => '../../../LICENSE' }
-  s.author           = { 'Your Company' => 'email@example.com' }
-
-  s.source           = { :http => 'https://github.com/flutter/packages' }
-  s.source_files     = 'Classes/**/*'
-  s.dependency 'FlutterMacOS'
-
-  s.platform = :osx, '10.11'
-  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
-  s.swift_version = '5.0'
-
-  s.test_spec 'Tests' do |test_spec|
-    test_spec.source_files = 'Tests/*.{swift}'
-  end
-end
diff --git a/packages/pigeon/platform_tests/macos_swift_unit_tests/pigeons/messages.dart b/packages/pigeon/platform_tests/macos_swift_unit_tests/pigeons/messages.dart
deleted file mode 100644
index 4fe745f..0000000
--- a/packages/pigeon/platform_tests/macos_swift_unit_tests/pigeons/messages.dart
+++ /dev/null
@@ -1,10 +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:pigeon/pigeon.dart';
-
-@HostApi()
-abstract class Api {
-  String getPlatform();
-}
diff --git a/packages/pigeon/platform_tests/test_plugin/example/macos/Podfile b/packages/pigeon/platform_tests/test_plugin/example/macos/Podfile
index 049abe2..47c1b18 100644
--- a/packages/pigeon/platform_tests/test_plugin/example/macos/Podfile
+++ b/packages/pigeon/platform_tests/test_plugin/example/macos/Podfile
@@ -31,6 +31,10 @@
   use_modular_headers!
 
   flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
+
+  target 'RunnerTests' do
+    inherit! :search_paths
+  end
 end
 
 post_install do |installer|
diff --git a/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcodeproj/project.pbxproj b/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcodeproj/project.pbxproj
index f520e42..706685f 100644
--- a/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcodeproj/project.pbxproj
+++ b/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcodeproj/project.pbxproj
@@ -22,13 +22,23 @@
 
 /* Begin PBXBuildFile section */
 		335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
+		33A341E6291ED3CF00D34E0F /* BasicCompileTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33A341E5291ED3CF00D34E0F /* BasicCompileTest.swift */; };
 		33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
 		33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
 		33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
 		33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
+		6315A7A2721DA1118B8E9021 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29E004D53850EB57FB6837A5 /* Pods_RunnerTests.framework */; };
+		875D4A972362F737CAF2FE4C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FC0DA6B36ADE41CB6E0674E /* Pods_Runner.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+		33A341DF291ED36900D34E0F /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 33CC10EC2044A3C60003C045;
+			remoteInfo = Runner;
+		};
 		33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
@@ -52,9 +62,13 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+		1D1B345C7A308AD53319BFE8 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
+		29E004D53850EB57FB6837A5 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
 		335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
-		33CC10ED2044A3C60003C045 /* test_plugin_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "test_plugin_example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+		33A341DB291ED36900D34E0F /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		33A341E5291ED3CF00D34E0F /* BasicCompileTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicCompileTest.swift; sourceTree = "<group>"; };
+		33CC10ED2044A3C60003C045 /* test_plugin_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = test_plugin_example.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
 		33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
 		33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
@@ -66,21 +80,44 @@
 		33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
 		33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
 		33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
+		34C7F8E51A95DED51F18178C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
 		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
+		84F9F76B1CDA5A3EA34A53A9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
 		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
+		9FC0DA6B36ADE41CB6E0674E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		CE9F6321D99B81775C2E58F7 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
+		D883C1052351847D8F8C1AC6 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
+		E2C8B3AD8F4C88A8093956DB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+		33A341D8291ED36900D34E0F /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				6315A7A2721DA1118B8E9021 /* Pods_RunnerTests.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		33CC10EA2044A3C60003C045 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				875D4A972362F737CAF2FE4C /* Pods_Runner.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		33A341DC291ED36900D34E0F /* RunnerTests */ = {
+			isa = PBXGroup;
+			children = (
+				33A341E5291ED3CF00D34E0F /* BasicCompileTest.swift */,
+			);
+			path = RunnerTests;
+			sourceTree = "<group>";
+		};
 		33BA886A226E78AF003329D5 /* Configs */ = {
 			isa = PBXGroup;
 			children = (
@@ -97,8 +134,10 @@
 			children = (
 				33FAB671232836740065AC1E /* Runner */,
 				33CEB47122A05771004F2AC0 /* Flutter */,
+				33A341DC291ED36900D34E0F /* RunnerTests */,
 				33CC10EE2044A3C60003C045 /* Products */,
 				D73912EC22F37F3D000D13A0 /* Frameworks */,
+				CA1DCAF3D143850A6677D34A /* Pods */,
 			);
 			sourceTree = "<group>";
 		};
@@ -106,6 +145,7 @@
 			isa = PBXGroup;
 			children = (
 				33CC10ED2044A3C60003C045 /* test_plugin_example.app */,
+				33A341DB291ED36900D34E0F /* RunnerTests.xctest */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -145,9 +185,25 @@
 			path = Runner;
 			sourceTree = "<group>";
 		};
+		CA1DCAF3D143850A6677D34A /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				34C7F8E51A95DED51F18178C /* Pods-Runner.debug.xcconfig */,
+				84F9F76B1CDA5A3EA34A53A9 /* Pods-Runner.release.xcconfig */,
+				E2C8B3AD8F4C88A8093956DB /* Pods-Runner.profile.xcconfig */,
+				CE9F6321D99B81775C2E58F7 /* Pods-RunnerTests.debug.xcconfig */,
+				D883C1052351847D8F8C1AC6 /* Pods-RunnerTests.release.xcconfig */,
+				1D1B345C7A308AD53319BFE8 /* Pods-RunnerTests.profile.xcconfig */,
+			);
+			name = Pods;
+			path = Pods;
+			sourceTree = "<group>";
+		};
 		D73912EC22F37F3D000D13A0 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				9FC0DA6B36ADE41CB6E0674E /* Pods_Runner.framework */,
+				29E004D53850EB57FB6837A5 /* Pods_RunnerTests.framework */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -155,15 +211,36 @@
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
+		33A341DA291ED36900D34E0F /* RunnerTests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 33A341E4291ED36900D34E0F /* Build configuration list for PBXNativeTarget "RunnerTests" */;
+			buildPhases = (
+				D8A37CA9DC49F3BACCA22E13 /* [CP] Check Pods Manifest.lock */,
+				33A341D7291ED36900D34E0F /* Sources */,
+				33A341D8291ED36900D34E0F /* Frameworks */,
+				33A341D9291ED36900D34E0F /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				33A341E0291ED36900D34E0F /* PBXTargetDependency */,
+			);
+			name = RunnerTests;
+			productName = RunnerTests;
+			productReference = 33A341DB291ED36900D34E0F /* RunnerTests.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
 		33CC10EC2044A3C60003C045 /* Runner */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
 			buildPhases = (
+				D30FEEB3988449C1EC3D1DBF /* [CP] Check Pods Manifest.lock */,
 				33CC10E92044A3C60003C045 /* Sources */,
 				33CC10EA2044A3C60003C045 /* Frameworks */,
 				33CC10EB2044A3C60003C045 /* Resources */,
 				33CC110E2044A8840003C045 /* Bundle Framework */,
 				3399D490228B24CF009A79C7 /* ShellScript */,
+				00374FFAF955BD99437C03D6 /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -181,10 +258,14 @@
 		33CC10E52044A3C60003C045 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastSwiftUpdateCheck = 0920;
+				LastSwiftUpdateCheck = 1400;
 				LastUpgradeCheck = 1300;
 				ORGANIZATIONNAME = "";
 				TargetAttributes = {
+					33A341DA291ED36900D34E0F = {
+						CreatedOnToolsVersion = 14.0;
+						TestTargetID = 33CC10EC2044A3C60003C045;
+					};
 					33CC10EC2044A3C60003C045 = {
 						CreatedOnToolsVersion = 9.2;
 						LastSwiftMigration = 1100;
@@ -216,11 +297,19 @@
 			targets = (
 				33CC10EC2044A3C60003C045 /* Runner */,
 				33CC111A2044C6BA0003C045 /* Flutter Assemble */,
+				33A341DA291ED36900D34E0F /* RunnerTests */,
 			);
 		};
 /* End PBXProject section */
 
 /* Begin PBXResourcesBuildPhase section */
+		33A341D9291ED36900D34E0F /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		33CC10EB2044A3C60003C045 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -233,6 +322,23 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
+		00374FFAF955BD99437C03D6 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
 		3399D490228B24CF009A79C7 /* ShellScript */ = {
 			isa = PBXShellScriptBuildPhase;
 			alwaysOutOfDate = 1;
@@ -271,9 +377,61 @@
 			shellPath = /bin/sh;
 			shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
 		};
+		D30FEEB3988449C1EC3D1DBF /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		D8A37CA9DC49F3BACCA22E13 /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
+		33A341D7291ED36900D34E0F /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				33A341E6291ED3CF00D34E0F /* BasicCompileTest.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		33CC10E92044A3C60003C045 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -287,6 +445,11 @@
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
+		33A341E0291ED36900D34E0F /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 33CC10EC2044A3C60003C045 /* Runner */;
+			targetProxy = 33A341DF291ED36900D34E0F /* PBXContainerItemProxy */;
+		};
 		33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
@@ -380,6 +543,51 @@
 			};
 			name = Profile;
 		};
+		33A341E1291ED36900D34E0F /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = CE9F6321D99B81775C2E58F7 /* Pods-RunnerTests.debug.xcconfig */;
+			buildSettings = {
+				BUNDLE_LOADER = "$(TEST_HOST)";
+				CURRENT_PROJECT_VERSION = 1;
+				GENERATE_INFOPLIST_FILE = YES;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 5.0;
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/test_plugin_example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/test_plugin_example";
+			};
+			name = Debug;
+		};
+		33A341E2291ED36900D34E0F /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = D883C1052351847D8F8C1AC6 /* Pods-RunnerTests.release.xcconfig */;
+			buildSettings = {
+				BUNDLE_LOADER = "$(TEST_HOST)";
+				CURRENT_PROJECT_VERSION = 1;
+				GENERATE_INFOPLIST_FILE = YES;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 5.0;
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/test_plugin_example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/test_plugin_example";
+			};
+			name = Release;
+		};
+		33A341E3291ED36900D34E0F /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 1D1B345C7A308AD53319BFE8 /* Pods-RunnerTests.profile.xcconfig */;
+			buildSettings = {
+				BUNDLE_LOADER = "$(TEST_HOST)";
+				CURRENT_PROJECT_VERSION = 1;
+				GENERATE_INFOPLIST_FILE = YES;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 5.0;
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/test_plugin_example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/test_plugin_example";
+			};
+			name = Profile;
+		};
 		33CC10F92044A3C60003C045 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
@@ -537,6 +745,16 @@
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+		33A341E4291ED36900D34E0F /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				33A341E1291ED36900D34E0F /* Debug */,
+				33A341E2291ED36900D34E0F /* Release */,
+				33A341E3291ED36900D34E0F /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
diff --git a/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index 48e7669..a33d94b 100644
--- a/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -37,6 +37,17 @@
          </BuildableReference>
       </MacroExpansion>
       <Testables>
+         <TestableReference
+            skipped = "NO"
+            parallelizable = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "33A341DA291ED36900D34E0F"
+               BuildableName = "RunnerTests.xctest"
+               BlueprintName = "RunnerTests"
+               ReferencedContainer = "container:Runner.xcodeproj">
+            </BuildableReference>
+         </TestableReference>
       </Testables>
    </TestAction>
    <LaunchAction
diff --git a/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcworkspace/contents.xcworkspacedata
index 1d526a1..21a3cc1 100644
--- a/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcworkspace/contents.xcworkspacedata
+++ b/packages/pigeon/platform_tests/test_plugin/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -4,4 +4,7 @@
    <FileRef
       location = "group:Runner.xcodeproj">
    </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
 </Workspace>
diff --git a/packages/pigeon/platform_tests/test_plugin/example/macos/RunnerTests/BasicCompileTest.swift b/packages/pigeon/platform_tests/test_plugin/example/macos/RunnerTests/BasicCompileTest.swift
new file mode 100644
index 0000000..c2db42e
--- /dev/null
+++ b/packages/pigeon/platform_tests/test_plugin/example/macos/RunnerTests/BasicCompileTest.swift
@@ -0,0 +1,20 @@
+// 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 XCTest
+@testable import test_plugin
+
+class MyApi: AllVoidHostApi {
+  func doit() {}
+}
+
+// Since the generator is almost entirely shared with iOS, this is currently
+// just testing that the generated code compiles for macOS (e.g., that the
+// Flutter framework import is correct).
+class BasicCompileTest: XCTestCase {
+  func testMakeApi() {
+    let api = MyApi()
+    XCTAssertNotNil(api)
+  }
+}
diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore b/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore
new file mode 100644
index 0000000..ebbbb45
--- /dev/null
+++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore
@@ -0,0 +1,4 @@
+# TODO(stuartmorgan): Remove this, so that review will show the effects of
+# changes on generated files. This will need a way to avoid unnecessary churn,
+# such as a flag to suppress version stamp generation.
+*.gen.swift
diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift
index b2285f4..699a7de 100644
--- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift
+++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift
@@ -5,19 +5,15 @@
 import Cocoa
 import FlutterMacOS
 
+/**
+ * This plugin is currently a no-op since only unit tests have been set up.
+ * In the future, this will register Pigeon APIs used in integration tests.
+ */
 public class TestPlugin: NSObject, FlutterPlugin {
   public static func register(with registrar: FlutterPluginRegistrar) {
-    let channel = FlutterMethodChannel(name: "test_plugin", binaryMessenger: registrar.messenger)
-    let instance = TestPlugin()
-    registrar.addMethodCallDelegate(instance, channel: channel)
   }
 
   public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
-    switch call.method {
-    case "getPlatformVersion":
-      result("macOS " + ProcessInfo.processInfo.operatingSystemVersionString)
-    default:
-      result(FlutterMethodNotImplemented)
-    }
+    result(FlutterMethodNotImplemented)
   }
 }
diff --git a/packages/pigeon/tool/run_tests.dart b/packages/pigeon/tool/run_tests.dart
index 642d2e7..d70ce0e 100644
--- a/packages/pigeon/tool/run_tests.dart
+++ b/packages/pigeon/tool/run_tests.dart
@@ -9,16 +9,7 @@
 ///
 /// usage: dart run tool/run_tests.dart
 ////////////////////////////////////////////////////////////////////////////////
-import 'dart:io'
-    show
-        Directory,
-        File,
-        Platform,
-        Process,
-        ProcessResult,
-        exit,
-        stderr,
-        stdout;
+import 'dart:io' show File, Platform, Process, exit, stderr, stdout;
 import 'dart:math';
 
 import 'package:args/args.dart';
@@ -281,28 +272,48 @@
 }
 
 Future<int> _runMacOSSwiftUnitTests() async {
-  const String macosSwiftUnitTestsPath =
-      './platform_tests/macos_swift_unit_tests';
-  final int generateCode = await _runPigeon(
-    input: '$macosSwiftUnitTestsPath/pigeons/messages.dart',
-    iosSwiftOut: '$macosSwiftUnitTestsPath/macos/Classes/messages.g.swift',
-  );
-  if (generateCode != 0) {
-    return generateCode;
-  }
-  final Directory oldCwd = Directory.current;
-  try {
-    Directory.current = Directory('$macosSwiftUnitTestsPath/macos');
-    final ProcessResult lintResult =
-        Process.runSync('pod', <String>['lib', 'lint']);
-    if (lintResult.exitCode != 0) {
-      return lintResult.exitCode;
+  const String macosSwiftUnitTestsPath = './$testPluginRelativePath';
+  const List<String> tests = <String>[
+    'all_void',
+  ];
+  int generateCode = 0;
+
+  for (final String test in tests) {
+    generateCode = await _runPigeon(
+      input: './pigeons/$test.dart',
+      iosSwiftOut:
+          '$macosSwiftUnitTestsPath/macos/Classes/${snakeToPascalCase(test)}.gen.swift',
+    );
+    if (generateCode != 0) {
+      return generateCode;
     }
-  } finally {
-    Directory.current = oldCwd;
   }
 
-  return 0;
+  const String examplePath = '$macosSwiftUnitTestsPath/example';
+  final Process compile = await _streamOutput(Process.start(
+    'flutter',
+    <String>['build', 'macos'],
+    workingDirectory: examplePath,
+    runInShell: true,
+  ));
+  final int compileCode = await compile.exitCode;
+  if (compileCode != 0) {
+    return compileCode;
+  }
+
+  final Process run = await _streamOutput(Process.start(
+    'xcodebuild',
+    <String>[
+      '-workspace',
+      'Runner.xcworkspace',
+      '-scheme',
+      'Runner',
+      'test',
+    ],
+    workingDirectory: '$examplePath/macos',
+  ));
+
+  return run.exitCode;
 }
 
 Future<int> _runIosSwiftUnitTests() async {