移动开发UI组件【免费下载链接】InstructionsCreate walkthroughs and guided tours (coach marks) in a simple way, with Swift.项目地址https://gitcode.com/gh_mirrors/in/Instructions点击查看免费下载本文以 fastlane/README.md 与 fastlane/Fastfile 为主体系统讲解 iOS 开源库 InstructionsSwift 编写的 coach marks / 引导页框架如何使用 fastlane 实现「构建框架与示例工程、运行单元与 UI 测试、生成并校验快照」的自动化流水线。读完本文你将掌握每个 lane 的调用方式、参数含义与底层实现能够基于这份配置搭建属于自己的 iOS 持续集成流程并理解快照测试从「录制参考图」到「回归校验」的完整工作机制。一、fastlane 在 Instructions 项目中的角色Instructions 是一个同时以 SwiftPM见 Package.swift、CocoaPods见 Instructions.podspec等形式分发的 iOS 框架仓库其工程以 workspace 形式组织见 Instructions.xcworkspace/contents.xcworkspacedata包含四个可构建的 target schemeScheme用途Instructions框架本体Instructions App Extensions面向 App Extensions 的框架变体Instructions Example演示示例 App含单元测试、UI 测试与快照测试Instructions App Extensions Example演示键盘扩展的示例工程fastlane 的作用就是把这四类 scheme 的「构建」与「测试」全部收敛为一条条可复用的 lane让本地开发与 CI 都能用同一套命令完成校验。fastlane/README.md 是 fastlane 在每次运行后自动重新生成的文档它忠实列出了当前 Fastfile 中暴露的所有 lane 与对应命令——它是 Fastfile 的「自动索引」本文将以这份清单为骨架结合 fastlane/Fastfile 的源码逐层拆解。二、环境准备与依赖安装在运行任何 lane 之前需要先完成两件事安装最新版本的 Xcode Command Line Toolsxcode-select --install通过 Bundler 安装 fastlane 及配套依赖。仓库的 Gemfile 声明了运行全部流水线所需的两个 gem# frozen_string_literal: true source https://rubygems.org gem fastlane gem slatherfastlane负责全部构建、测试 laneslather用于生成代码覆盖率报告CI 中通过slather coverage -x --build-directory Build/生成 cobertura 格式覆盖率并上报。Gemfile.lock 锁定了当时依赖树fastlane 2.216.0、slather 2.7.5支持 arm64-darwin 与 x86_64-linux 平台。安装命令bundle install之后所有 lane 统一通过 Bundler 前缀调用保证 CI 与本地使用完全一致的 fastlane 版本bundle exec fastlane ios lane_name说明仓库的 fastlane/Appfile 目前仅保留了注释模板app_identifier与apple_id均未启用。原因在于本仓库的 lane 只执行构建与测试不涉及上传 App Store / TestFlight 等需要 Apple 账号鉴权的操作因此不需要在 Appfile 中配置 bundle identifier 与 Apple ID。若你要在自己的项目中复用这套 lane再按需取消注释即可。三、lane 全景一览fastlane/README.md 列出的全部 lane 及其命令、用途如下Lane 名称命令用途ios build_all[bundle exec] fastlane ios build_all构建全部 targetios build_frameworks[bundle exec] fastlane ios build_frameworks构建框架Instructions 及其 App Extensions 变体ios build_examples[bundle exec] fastlane ios build_examples构建示例工程ios build[bundle exec] fastlane ios build构建指定的 schemeios generate_snapshots[bundle exec] fastlane ios generate_snapshots为所有模拟器生成新的快照参考图ios test_all[bundle exec] fastlane ios test_all运行完整测试套件ios test_snapshots[bundle exec] fastlane ios test_snapshots运行快照回归测试ios test_unit_and_ui[bundle exec] fastlane ios test_unit_and_ui运行单元测试与 UI 测试其中build_all与test_all是复合 lane分别聚合了「两个构建子流程」与「两个测试子流程」构成了仓库的核心 CI 路径。四、Fastfile 全局配置解读进入各 lane 之前先看 fastlane/Fastfile 中定义的全局常量它们贯穿所有 lanedefault_platform(:ios) platform :ios do DEVICES [ iPad (10th generation), iPhone 15 Pro, iPhone SE (3rd generation) ] WORKSPACE Instructions.xcworkspace INSTRUCTIONS_SCHEME Instructions APP_EXTENSION_INSTRUCTIONS_SCHEME Instructions App Extensions EXAMPLE_SCHEME Instructions Example APP_EXTENSION_EXAMPLE_SCHEME Instructions App Extensions Example DERIVED_DATA_PATH Build/DEVICES测试覆盖的三款模拟器设备——iPad第 10 代、iPhone 15 Pro、iPhone SE第 3 代同时覆盖了 iPad 与不同屏幕形态的 iPhone确保快照测试在横竖屏、异形屏刘海等场景下都有参考WORKSPACE统一使用Instructions.xcworkspace而非单一 xcodeproj以便同时编译框架与两个示例工程四个 scheme 常量区分「框架本体 / 框架扩展变体 / 示例 App / 扩展示例 App」四类 targetDERIVED_DATA_PATH把 DerivedData 固定到仓库根目录的Build/这一约定同时被 CI 中的 slather 覆盖率收集步骤复用--build-directory Build/。五、构建 lane从复合到单点5.1 build_all一键构建全部 targetdesc Build all targets lane :build_all do build_frameworks build_examples endbuild_all依次调用build_frameworks与build_examples是「全量构建」的入口等价于把框架与示例工程全部编译一遍用于验证整个仓库可构建。5.2 build_frameworks 与 build_examplesdesc Build frameworks lane :build_frameworks do build(scheme: INSTRUCTIONS_SCHEME) build(scheme: APP_EXTENSION_INSTRUCTIONS_SCHEME) end desc Build examples lane :build_examples do build(scheme: EXAMPLE_SCHEME) build(scheme: APP_EXTENSION_EXAMPLE_SCHEME) end两个 lane 都只是以不同的 scheme 参数调用底层的buildlanebuild_frameworks验证框架本体Instructions与 App Extensions 变体Instructions App Extensions能否编译通过build_examples验证两个示例工程Instructions Example、Instructions App Extensions Example能否编译通过。5.3 build单一 scheme 的构建实现desc Build the given scheme lane :build do |values| build_app( workspace: WORKSPACE, scheme: values[:scheme], clean: true, skip_archive: true, skip_codesigning: true ) endbuild接收values[:scheme]作为参数通过 fastlane 内建的build_appaction 完成编译。三个关键参数的含义clean: true每次构建都执行 clean确保产物不受增量编译缓存污染skip_archive: true仅编译、不归档因为这里只需要验证「能构建」不需要产出可分发的归档包skip_codesigning: true跳过代码签名。库的构建验证不涉及真机安装或发布跳过签名即可在无开发者证书的 CI 环境直接运行。六、测试 lane三层测试体系6.1 test_all完整测试套件入口desc Run full test suite lane :test_all do test_snapshots() test_unit_and_ui() endtest_all串联两条测试流水线先跑快照测试再跑单元与 UI 测试。这也是 .github/workflows/continuous-integration.yml 中 CI 主流程调用的 lanebundle exec fastlane test_all。6.2 test_unit_and_ui单元测试 UI 测试desc Run Unit UI tests lane :test_unit_and_ui do run_tests( workspace: WORKSPACE, scheme: EXAMPLE_SCHEME, testplan: UnitUI, devices: DEVICES[0], prelaunch_simulator: true, derived_data_path: DERIVED_DATA_PATH, ) end该 lane 使用run_tests在Instructions Examplescheme 下执行名为UnitUI的测试计划testplan。Examples/UnitUI.xctestplan 定义了这个计划的测试目标InstructionsExampleUITestsUI 测试parallelizableInstructionsUnitTests单元测试parallelizable两者均标记为parallelizable可在模拟器上并行执行以缩短总耗时。该 lane 只在DEVICES[0]iPad 第 10 代上运行prelaunch_simulator: true用于在测试开始前预热模拟器减少首轮启动带来的超时抖动。6.3 test_snapshots快照回归测试desc Run snapshot tests lane :test_snapshots do run_tests( workspace: WORKSPACE, scheme: EXAMPLE_SCHEME, testplan: Snapshot, only_test_configurations: Test Snapshots, devices: DEVICES, prelaunch_simulator: true, derived_data_path: DERIVED_DATA_PATH, ) end快照测试在全部三台模拟器DEVICES上运行使用Snapshot测试计划中的Test Snapshots配置。Examples/Snapshot.xctestplan 中该配置的关键是两条环境变量同时出现在defaultOptions中作用于整个计划FB_REFERENCE_IMAGE_DIR→$(SRCROOT)/Example/Snapshot Tests/Supporting Files/Snapshots/ReferenceImages参考图目录即$(SRCROOT)/Example/Snapshot Tests/Supporting Files/Snapshots/ReferenceImages_64仓库中以_64后缀落盘IMAGE_DIFF_DIR→$(SRCROOT)/Example/Snapshot Tests/Supporting Files/Snapshots/FailureDiffs测试失败时的差异图目录。该计划的测试目标是InstructionsSnapshotTests同样 parallelizable入口文件为 Examples/Example/Snapshot Tests/DefaultExampleSnapshotTests.swift。它的setUp中有两行与 fastlane 流水线直接呼应的逻辑fileNameOptions [.screenScale] recordMode ProcessInfo.processInfo.environment[RECORD_MODE] ! nil也就是说测试进程是否处于「录制模式」完全由环境变量RECORD_MODE是否存在决定——这正是下面generate_snapshotslane 切换测试行为的开关。6.4 generate_snapshots生成/更新参考图desc Generate new snapshots for all simulators lane :generate_snapshots do run_tests( workspace: WORKSPACE, scheme: EXAMPLE_SCHEME, testplan: Snapshot, only_test_configurations: Generate Snapshots, devices: DEVICES ) end与test_snapshots的差异只有一处only_test_configurations从Test Snapshots变为Generate Snapshots。后者的配置见 Examples/Snapshot.xctestplan额外注入了environmentVariableEntries : [ { key : RECORD_MODE, value : true }, ... ]因此当快照测试用例检测到RECORD_MODEtrue时DefaultExampleSnapshotTests.swift 会把recordMode置为真测试不再比对参考图而是把当前画面写盘作为新的参考图。这就是 Instructions 快照工作流的核心闭环改动 UI / 布局或新增测试用例 │ ▼ fastlane ios generate_snapshots RECORD_MODEtrue录制新参考图 │ ▼ 提交新生成的 ReferenceImages │ ▼ fastlane ios test_snapshots 无 RECORD_MODE回归比对快照用例本身覆盖了两种演示维度见 DefaultExampleSnapshotTests.swift三种展示上下文independentWindow独立窗口、sameWindow同窗口、controller控制器内两种行为模式testFlowIn*教练标记依次推进的完整流程与testRotationIn*流程中途旋转屏幕。每个用例对同一场景连续截取 5 张快照for _ in 0..5比对时使用perPixelTolerance: 0.1与overallTolerance: 0.002两档容差见 DefaultExampleSnapshotTests.swift。此外为保证快照稳定测试会通过--SnapshotTests启动参数隐藏状态栏见 Examples/Example/Snapshot Tests/Extensions/XCUIApplicationLaunch.swift并借助 DeviceKit 扩展按设备型号精确裁剪状态栏 / Home Indicator 区域见 Examples/Example/Snapshot Tests/Extensions/UIImageExtensions.swift确保参考图不受系统 UI 干扰、可跨设备复现。七、与 CI 的集成一条命令跑完整套件仓库的 .github/workflows/continuous-integration.yml 展示了这条流水线在实际 CI 中的用法。其testjob 在macos-13Xcode 14.3.1上执行bundle install bundle exec fastlane test_all即一次调用聚合了test_snapshotstest_unit_and_ui。CI 中还有两个与 fastlane 配置强相关的配套环节失败差异图上传若test_all失败把Examples/Example/Snapshot Tests/Supporting Files/Snapshots/FailureDiffs/作为 artifact 上传方便人工定位快照偏差覆盖率收集通过slather coverage -x --build-directory Build/生成 cobertura 格式覆盖率再由 CodeClimate 上报。其配置见 .slather.yml——source_directory: Sources、output_directory: Tests并忽略Examples/*示例代码不计入框架覆盖率。此外 CI 还通过独立的 InstructionsPackageTest 仓库分别验证 SwiftPM、CocoaPods、Carthage 三种安装方式下的导入与构建与本仓库 Fastfile 的构建 lane 形成互补Fastfile 管「仓库内部全量构建 测试」CI 额外管「第三方集成方式可用性」。八、常见问题与实操建议为什么所有命令都要加bundle execfastlane/README.md 中每个 lane 的调用方式都写作[bundle exec] fastlane ...方括号表示可选。推荐始终使用bundle exec以锁定 Gemfile.lock 中记录的 fastlane 2.216.0 版本避免本机全局 fastlane 版本差异导致行为不一致。改完 UI 后快照测试红了怎么办这是快照测试的正常预期UI 变化导致画面与参考图不一致。正确的处理顺序是先人工核对FailureDiffs目录下的差异图确认改动符合预期再运行bundle exec fastlane ios generate_snapshots重新录制参考图最后提交新参考图并跑一遍ios test_snapshots验证。只想快速验证一个 scheme 能否编译运行bundle exec fastlane ios build scheme:YourScheme。注意build是唯一接收参数的 lane其余 lane 均已固化 scheme。新增测试用例后如何纳入流水线单元测试加入InstructionsUnitTests、UI 测试加入InstructionsExampleUITests即可被 Examples/UnitUI.xctestplan 自动拾取新增快照用例则需在InstructionsSnapshotTests中编写并先跑generate_snapshots生成参考图。九、总结本文以 fastlane 自动生成的 lane 清单为索引逐条对照 fastlane/Fastfile 的实现完整还原了 Instructions 仓库的自动化流水线四条构建 lanebuild_all/build_frameworks/build_examples/build负责四个 scheme 的编译验证四条测试 lanetest_all/test_snapshots/test_unit_and_ui/generate_snapshots分别承载单元测试、UI 测试与快照测试其中RECORD_MODE环境变量配合 Examples/Snapshot.xctestplan 的两种配置实现了「录制参考图 ↔ 回归比对」的可逆闭环。这套配置同时服务于本地开发与 GitHub Actions 持续集成可以作为任何 iOS 库项目搭建「构建 测试 快照 覆盖率」一体化流水线的直接范本。赞分享移动开发UI组件【免费下载链接】InstructionsCreate walkthroughs and guided tours (coach marks) in a simple way, with Swift.项目地址https://gitcode.com/gh_mirrors/in/Instructions点击查看免费下载相关推荐终极BottomNavigation测试指南从单元测试到UI自动化的完整实践方案终极BottomNavigation测试指南从单元测试到UI自动化的完整实践方案 BottomNavigation是一个帮助开发者轻松实现Google底部导航语言运行时后端开发工具包管理器前端构建测试WPF测试策略单元测试与UI自动化测试全方案WPF测试策略单元测试与UI自动化测试全方案 你还在为WPF应用的测试覆盖率发愁吗是否在单元测试与UI自动化测试之间难以平衡本文将系统讲解WPF应用的测试桌面应用前端UI组件LCD Image Converter重新定义嵌入式图像与字体转换的完整解决方案LCD Image Converter重新定义嵌入式图像与字体转换的完整解决方案 LCD Image Converter是一款革命性的专业图像转换工具专为嵌桌面应用嵌入式开发工具图像处理上一篇conventionalcommits.org统计分析全球开发者使用情况报告下一篇Formily Form 模型完全指南formily/core 核心表单模型 API 深入解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?