CI/CD 2026年10月18日 约 22 分钟 fastlane scan 远程 Mac 测试

fastlane scan 如何在远程 Mac 跑测试?2026 指南

这篇指南面向需要在远程 Mac 执行 iOS 自动化测试、并维护构建节点的开发者与 CI 工程师。结论是先验证项目 scheme、模拟器目标和结果文件,再把 lane 接入持续集成;模拟器测试不能代替真机验收。

fastlane scan 如何在远程 Mac 跑测试?2026 指南

这篇指南面向需要在远程 Mac 执行 iOS 自动化测试、并维护构建节点的开发者与 CI 工程师。结论是先验证项目 scheme、模拟器目标和结果文件,再把 lane 接入持续集成;模拟器测试不能代替真机验收。

症状:fastlane scan 命令已经启动,但远程 Mac 上的测试不动、找不到模拟器,或失败后没有结果可查。
最快解法:先确认这台 Mac 实际选中的 Xcode、共享 scheme 和已安装的 iOS Simulator,再用一个小测试目标试跑并保存结果;通过后再接入 CI。fastlane scan 能调用测试流程,不能代替 Mac 执行环境或测试结果本身;需要设备行为覆盖时,另做真机验证。

负责 iOS 自动化测试的开发者,可以用本文把本机测试流程迁移到远程节点,并检查两边结果是否一致。
负责 CI 节点维护的工程师,可以据此安排任务入口、失败日志和结果文件的留存。
没有长期可用 Mac 的独立开发者或小团队,则可以用试跑结果判断远程 Mac 是否适合当前工作流。

01

远程 Mac 测试基线:先核对项目与工具链

把项目搬到远程 Mac 后,先确认“同一个提交是否能在这里被正确发现和构建”,不要从完整测试套件或正式流水线起步。fastlane 的 run_tests(也可用 scan 调用)负责整理并触发测试,底层仍依赖 Xcode 的测试工具运行;实际执行地点必须具备项目所需的 Mac 工具链。fastlane 的 iOS 测试说明介绍了在 Fastfile 中调用 run_tests;相关参数包括 scheme、设备、测试计划与结果目录。(run_tests 官方参数文档)

我们建议先记录以下基线,之后每次节点或项目变更都能对照:

  • 代码与工程入口:记录提交标识、工作区或工程文件路径,确认测试所需的依赖文件已经提交或可以按项目既有流程解析。若项目使用工作区,不要误把工程文件当成测试入口。
  • Xcode 选择:在远程 Mac 执行 xcode-select -p、xcodebuild -version,核对实际选中的开发者目录与项目要求是否一致。xcodebuild、simctl 等命令属于 Xcode 工具链;只安装独立命令行工具包,不一定能提供完整测试执行条件。Apple 的 Xcode 命令行工具参考列出了相关工具;独立命令行工具包与完整 Xcode 的安装方式也应按项目需求核对。
  • scheme 与测试目标:确认 scheme 已共享,并且其 Test 动作包含预期的单元测试或 UI 测试目标。scheme 在本机 Xcode 界面可用,不代表远程检出的仓库也能发现同一份配置。
  • Ruby 与 fastlane 依赖:按项目当前做法选择 Ruby 管理方式;使用 Gemfile 时,提交 Gemfile.lock,在远程按锁定依赖安装并通过 bundle exec 调用 fastlane。fastlane 的 CI 文档也提供项目级依赖安装与锁文件管理示例,但具体 Ruby 和 fastlane 版本应以项目配置及官方当前要求为准。fastlane 的 CI 集成说明

这里有个容易漏掉的边界:Xcode 版本选对了,不等于目标 Simulator runtime 已经安装。先把项目所需的平台运行时列入环境基线;缺少运行时或设备类型时,命令行可能找不到预期目标,报错看起来却像是 fastlane 配置问题。

02

首次配置:把测试入口固定在 Fastfile

把手工试跑成功的命令收进 lane,目的是让本机与远程执行使用同一组参数,而不是每次靠 shell 历史记录补齐选项。以下示例里的工程路径、scheme、设备名和测试计划均为占位符,不能原样当作项目配置:

platform :ios do
  lane :test do
    run_tests(
      workspace: "<WORKSPACE_PATH>",
      scheme: "<SHARED_TEST_SCHEME>",
      testplan: "<TEST_PLAN_NAME>",
      devices: ["<AVAILABLE_SIMULATOR_NAME>"],
      output_directory: "<RESULTS_DIRECTORY>",
      result_bundle: true
    )
  end
end

如果项目使用 .xcodeproj,按实际情况改为 project,不要同时填入互不匹配的工程入口。若项目没有命名测试计划,则删除 testplan;如果有多个计划,指定与本次测试目的相符的一个。Apple 将测试计划定义为 scheme 测试动作所运行的测试与配置集合,因此计划选错时,命令可以成功结束,却没有覆盖团队原本要检查的测试。Apple 的测试计划说明介绍了计划与 scheme 测试动作的关系。

运行入口优先沿用仓库的依赖锁定方式,例如:

bundle install
bundle exec fastlane test

若暂时没有 lane,也可以用 fastlane run_tests 做一次受控调用,再把稳定参数收进 Fastfile。fastlane 文档说明 scan 是 run_tests 的别名,并支持通过 lane 组织重复测试任务;相关参数文档还列出 testplan、devices、output_directory 和 result_bundle 等配置项。

⚠️ 不要为了让配置“看起来固定”而写死远程 Mac 上未核实的设备型号或系统版本。目标清单要以该节点实际可用的模拟器为准;节点重装 Xcode 或增删运行时后,需要重新核验。

03

首次试跑:找不到 iOS Simulator 时先查可用清单

如果 fastlane scan 找不到 iOS Simulator,先不要立刻重装 fastlane。按执行顺序核对远程 Mac 的 Xcode 选择、已安装的 iOS Simulator runtime,以及目标设备是否确实存在:

xcode-select -p
xcodebuild -version
xcrun simctl list devices available

再对照 Fastfile 中的设备占位值,确认名称与远程清单对应。Apple 的命令行工具参考说明 simctl 用于管理模拟器;fastlane 的参数说明也包括设备选择相关配置。

目标可见后,先运行最小测试:选定一个共享 scheme、一个测试目标和一台可用模拟器。若首轮失败,按阶段记录,而不是笼统地标记为“fastlane 失败”:

  • 依赖解析阶段:检查项目包管理器是否能解析锁定的依赖,以及远程环境是否能访问所需资源。
  • 构建阶段:核对工程入口、scheme、签名设置和构建日志;构建失败时,测试断言尚未开始。
  • 模拟器启动阶段:对照设备清单、runtime 和启动日志;目标不可见与模拟器启动后崩溃是不同问题。
  • 测试执行阶段:确认测试目标实际启动,并检查失败用例、断言信息和测试结果,而不是只看命令是否返回。

fastlane scan 走的是 Xcode 测试流程,因此终端输出、fastlane 原始构建日志和 Xcode 测试结果要一起看。文档说明可通过配置选择工程、scheme 和设备,并保存原始构建日志;这也是把失败归到正确阶段的依据。

04

失败时保留结果:让 CI 能取回日志与结果包

远程 Mac CI 在测试失败后能否留下可复核材料,取决于流水线是否在失败路径仍收集测试输出;只在成功步骤上传文件,恰好会丢掉最需要诊断的那次运行。示例 lane 已设置结果目录与 result_bundle: true,接入具体 CI 后,还要把该目录配置为任务产物,并验证失败任务结束后仍能下载。

Xcode 通过命令行运行测试时会生成 .xcresult 结果包,其中可包含测试会话结果、已启用的代码覆盖率与其他日志;它与简化的控制台摘要用途不同,适合后续在 Xcode 中复核。Apple 的测试运行与结果解读文档说明了结果包的内容与查看方式。

为避免“命令失败,上传步骤也被跳过”,检查流水线的失败处理逻辑:

  • 把原始日志与 .xcresult 放在明确、可预测的输出目录。
  • 将归档或上传设置为失败任务后仍执行;具体语法按所用流水线系统配置,不要假设所有系统默认行为相同。
  • 在任务完成后检查文件是否存在、能否下载、是否能在 Xcode 中打开;仅看到上传步骤显示成功,不足以证明结果完整。
  • 按团队的数据保留和访问权限规定处理结果包。结果可能包含诊断信息,不要未经审查就开放给无关人员。
方案 工程适配评分(定性) 主要优势 需要承担的边界
本地 Mac 直接试跑 高 便于快速确认工程、scheme 与测试逻辑 结果受本机工具链和工作区状态影响,不能单独证明远程节点配置正确
远程 Mac 手动试跑 高 能验证目标节点上的 Xcode、模拟器和结果取回 尚未覆盖流水线触发、失败处理与任务归档
远程 Mac 接入 CI 高,前提是试跑已通过 测试入口和产物归档可纳入团队的持续流程 仍需验证失败时留档、节点恢复和实际设备覆盖
仅使用 Linux 节点执行 低,不适合原生 Xcode 模拟器测试 可继续承担与 macOS 无关的任务 不能提供本文所需的 Mac/Xcode 测试执行环境

评分是按流程适配和验收闭环作出的工程判断,不是硬件性能测试或成功率数据。若团队只缺少短期试跑环境,先做远程手动验证更合适;若已经需要每次提交自动触发,再把同一 lane 接入 CI。fastlane 的 CI 示例说明可用项目依赖和 lane 调用测试,并单独配置日志与测试产物收集;流水线细节仍应按团队实际系统调整。

05

上线验收:模拟器通过不等于真机完成验收

把一次测试命令跑通,只能证明当前提交在当前配置下执行到了相应测试阶段;它不自动证明完整 CI 已经可复现,也不代表 iOS 应用已完成真实设备验收。Apple 明确指出,模拟器不复现真实设备的全部性能与功能差异;若要确认应用在真实设备上的行为,还需要在相应设备上运行验证。Apple 关于模拟器与实体设备的说明进一步说明了这两类目标的边界。

接入正式流水线前,我们建议按这一轮验收结果作决定:

  • 继续试运行:如果远程手动执行稳定,但触发、失败后留档或下载结果还没验证,先修正流水线,不要把“命令可运行”当作上线标准。
  • 接入正式 CI:同一提交在远程节点可找到目标设备、运行预期测试,并且成功与失败两条路径都能保留日志和结果包;再验证任务重跑及节点重启后的恢复。
  • 增加真机验证:只有当项目依赖真实硬件特性、真实设备性能表现或模拟器不能覆盖的行为时,才安排对应真机测试。模拟器回归可保留为快速反馈层,真机验收则针对项目需要补足。
  • 调整节点或方案:若目标 Xcode、运行时或测试依赖无法在现有节点满足,先确认项目要求与可用环境的差距,再决定变更工具链、测试安排或执行节点。

排查已发现的 Xcode 环境选择问题时,可先参照远程 Mac 上的 Xcode 工具链检查整理节点基线;如果当前没有可用于试跑的 Mac,再查看远程 Mac 方案,重点核对项目所需工具链、使用周期与结果取回方式,而不是先假设某种配置一定兼容。

如果目前用 Linux 承担全部任务,遇到 macOS 专属构建和 Simulator 测试时仍需另找 Mac 执行环境;如果依赖开发者自己的本机 Mac,节点可用性又会随个人设备状态变化;自行维护专用 Mac 则要额外负责工具链更新、依赖隔离和故障恢复。对只在试跑或阶段性测试时需要 Mac 的团队,先用一个真实 scheme 验证远程执行闭环,再评估按需租用是否匹配持续时间与工具链要求,通常比未经验证就购买硬件更稳妥。需要长期、稳定高负载执行或必须连接指定物理设备的团队,则应先按实际运维与接口要求评估自有设备或专门的真机测试安排。