✅ 适合:需要反复验证多语言界面、截图和发布产物的独立开发者,尤其适合没有常驻本地 Mac、但仍要持续运行 Xcode 测试的团队。
❌ 不适合:只根据翻译完成率判断发布质量的项目,因为绿色状态并不能证明运行时布局、地区格式和 Archive 资源都没有问题。
String Catalog 多语言测试不应被理解成“检查翻译是否全部完成”。可执行的方案是先固定字符串提取规则和语言地区矩阵,再用 Test Plan、UI 测试、截图与最终构建产物完成闭环;如果本地没有一台长期保留 Xcode、模拟器和测试结果的 Mac,把流程部署到远程 Mac 更适合持续回归。
这篇文章适合三类人:维护多语言 SwiftUI App、希望自动发现新增或失效字符串的单人开发者;正在从 strings、stringsdict、Storyboard 或 XIB 逐步迁移的 UIKit 存量项目;以及需要在多个市场、地区和界面尺寸上执行发布验收的小团队。
00先把 String Catalog 多语言测试拆成五类证据
String Catalog 管理的不只是翻译文本,还涉及语言、复数、设备变体和本地化资源。Apple 的文档明确说明,Xcode 可以在构建时提取可本地化字符串,并将其更新到 String Catalog;但这只说明“字符串进入了目录”,不代表它在运行时一定显示正确。可先参考 Apple 关于 String Catalog 的官方说明。
为了避免把不同问题混成一个“本地化通过”,建议把验收拆成下面五层:
| 验证层 | 要回答的问题 | 主要证据 |
|---|---|---|
| 字符串提取 | 新增文本是否进入 String Catalog? | .xcstrings 变更、构建日志 |
| 翻译状态 | 每个目标语言是否有可用翻译、复数和变体? | String Catalog 状态、导出文件 |
| 运行时语言 | App 在指定语言下是否真的替换文本? | UI 测试、运行截图 |
| 地区与布局 | 日期、货币、数字、RTL 和长文本是否正常? | Test Plan 配置、UI 断言 |
| 发布产物 | Archive 是否包含预期语言和资源? | .xcarchive、App Bundle 检查 |
其中最容易被忽略的是最后一层。编辑器中的绿色翻译状态属于项目编辑证据,不能代替安装后运行证据,更不能代替最终 Archive 验收。
用关键用户路径控制测试范围
不要一开始把所有页面都放进本地化 UI 测试。优先选择登录、订阅购买、核心创作、导出结果和错误提示等路径,因为这些页面通常同时包含按钮、动态文本、复数、金额或网络状态。
每条路径至少保留一个成功分支和一个失败分支。例如购买页面不能只检查“购买”按钮,还应覆盖价格加载失败、订阅不可用和恢复购买等状态。这样能够更早发现某个语言下的错误提示没有提取,或者长文本把主要操作按钮挤出屏幕。
01按项目类型建立不同的自动化起点
SwiftUI 项目:先查提取,再查变体
SwiftUI 视图中的部分用户可见字符串会通过 LocalizedStringKey 自动进入 String Catalog,但普通 Swift 代码中的人类可读文本仍然需要使用本地化 API。Apple 对这一区别有明确说明,可查看 SwiftUI 与其他代码的本地化字符串提取规则。
建议先建立一个最小样本,至少包含:
- 普通标题和按钮文本;
- 一个带插值参数的字符串;
- 一个单复数变化;
- 一个长文本或多行说明;
- 一个需要设备或界面变体的文本。
然后执行一次 Build,检查新增代码是否进入预期的 .xcstrings。如果某段文本没有出现,不要直接手工把它复制进目录,而应先确认代码是否使用了正确的本地化 API、是否进入了正确的 tableName,以及该代码是否属于实际构建的 Target。
仅看翻译百分比是不够的。某个语言达到完整状态,仍可能存在插值顺序错误、复数规则未覆盖或文本在小屏设备上截断的问题。
UIKit 与混合项目:把旧资源边界标出来
UIKit 或混合项目经常同时存在 String Catalog、.strings、.stringsdict、Storyboard、XIB 和 Info.plist 中的可本地化文本。迁移时最危险的做法,是为了格式统一而一次性替换全部资源。
更稳妥的方式是按模块迁移:
- 先列出 App、扩展、Framework 和测试 Target 的本地化资源;
- 标记每个资源属于哪个 Target,以及最终是否进入 App Bundle;
- 选择一个功能模块迁移到 String Catalog;
- 构建并运行该模块的语言测试;
- 确认旧资源没有被重复加载,再处理下一个模块。
UIKit 项目要特别检查 Storyboard 和 XIB 中的控件文本,因为代码搜索不一定能发现这些资源。对于扩展和 Framework,也不能只检查主 App 的目录;最终证据应来自构建后的 Bundle 和实际运行界面,而不是项目导航器里的文件列表。
02用语言地区矩阵配置 Xcode 和 Test Plan
语言和地区不是同一个变量。语言决定字符串使用哪种本地化内容,地区则会影响日期、货币、数字、单位和部分格式化结果。Apple 的 本地化运行测试文档 说明,可以在 Scheme 或测试配置中选择 App Language 与 App Region。
建议建立一张小而真实的矩阵:
| 测试配置 | 适合覆盖的风险 | 必查内容 |
|---|---|---|
| 英语 + 美国 | 基准路径和默认资源 | 主流程、金额、日期 |
| 德语 + 德国 | 长文本和复合词 | 按钮宽度、标题换行 |
| 法语 + 法国 | 文本长度与格式化 | 数字、货币、说明文字 |
| 日语 + 日本 | 字符宽度与换行 | 导航、表单、辅助说明 |
| 阿拉伯语 + 代表地区 | RTL 布局 | 对齐、图标方向、手势 |
| 中文 + 目标市场地区 | 主要用户市场 | 核心流程和发布截图 |
这张表不是要求每个项目都照抄,而是提醒开发者按真实市场选择组合。一个只支持英语、日语和简体中文的 App,没有必要为所有地区建立完整模拟器矩阵;但如果产品涉及订阅、发票或本地化价格,地区测试就不能只设置语言而忽略 Region。
在 Test Plan 中,每种关键组合应独立成为一个 Configuration。Apple 的 Test Plan 配置说明列出了 Application Language、Application Region、Localization Screenshots 和测试附件等选项。这样同一组 UI 测试可以在不同配置下复用,而不必复制多套测试代码。
用截图验证界面,但不要把截图当营销素材
如果要把本地化界面交给翻译人员或内部审核,Test Plan 可以为不同语言配置生成截图。Apple 的 本地化截图文档说明,开启 Localization Screenshots 后,Xcode 会保存对应语言的截图,并附带字符串与画面位置的关联信息。
截图应带有环境标识,例如语言、地区、构建号和测试配置名称。它们主要用于:
- 复核长文本是否截断;
- 对照翻译上下文;
- 检查错误提示和空状态;
- 记录发布前回归证据。
不要直接把自动化测试截图当作 App Store 营销素材。测试截图的尺寸、状态和内容通常服务于验收,不一定符合商店展示要求。
03把本地化任务拆成可重跑的远程 Mac 流程
String Catalog 能否在持续集成中自动检查,关键不在于“是否使用某个云端工具”,而在于任务是否被拆开,并且每一步都有可保存的证据。推荐按下面 7 步部署:
-
固定构建入口
明确项目、Scheme、Configuration、测试账号和依赖安装方式,避免本地开发者使用不同 Scheme 导致结果不一致。 -
先执行字符串提取或导出
使用 Xcode 菜单或xcodebuild -exportLocalizations导出指定语言。Apple 的 本地化导出文档给出了命令参数和-includeScreenshots选项。 -
保存目录差异
将本次.xcstrings、XLIFF 或导出目录与基线比较,重点关注新增 key、删除 key、未翻译内容和异常变体。 -
按 Test Plan 运行核心 UI 测试
每个语言地区配置单独输出日志和测试结果,不要让一个语言失败后直接掩盖其他配置的状态。 -
生成并归档截图
对关键页面开启本地化截图,同时保留测试附件和失败时的诊断信息。 -
构建 Archive 并检查 Bundle
检查最终产物中是否包含预期语言目录、资源和扩展 Target 内容。不能只检查源码目录,因为资源归属错误可能在构建阶段才暴露。 -
验证重启、断线和重跑
在远程 Mac 上模拟 SSH 断线、主机重启和任务重新执行,确认结果目录不会被覆盖成无法追溯的状态,并且失败任务可以从明确阶段重新开始。
⚠️ 经验提醒:依赖模拟器和截图的任务通常需要图形登录会话。SSH 能连接主机,不等于 UI 测试已经获得可用的图形环境;如果这一区别没有提前验证,脚本可能能完成编译,却在启动模拟器或抓取截图时失败。
如果项目还需要把翻译文件导回工程,可使用 xcodebuild -importLocalizations,或按 Apple 的 本地化导入说明检查导入警告。导入成功后仍要重新构建和测试,不能把“文件已导入”当成运行时通过。
04用条件分支决定测试规模和远程 Mac 方案
下面的条件列表可以帮助独立开发者确定自动化深度:
- 若项目只有 1—2 种语言、页面少于核心路径范围,且每次发布都由同一人手动验收,则先采用本地 Test Plan 和少量 UI 测试;否则回退到完整的语言地区矩阵。
- 若项目包含订阅、货币、复数或 RTL 布局,则至少保留代表性地区配置;否则不能只运行默认语言。
- 若 SwiftUI 文本提取稳定,但 UIKit、Storyboard 或扩展资源仍未迁移,则按 Target 和模块逐步迁移;否则不要为了统一格式一次性重写全部资源。
- 若 CI 只需要编译和单元测试,则普通命令行环境可能足够;若需要模拟器 UI 测试、截图和本地化验收,则选择具备图形会话的远程 Mac。
- 若任务需要每天或每次提交都执行,并且本地 Mac 经常关机、磁盘不足或被其他工作占用,则适合把测试环境长期放在远程 Mac;若项目需要物理设备、专用外设或本地调试硬件,则应保留本地设备作为主环境。
如果需要评估远程主机是否适合持续测试,可以先参考 NUKCLOUD 的 Mac 远程使用入口,再根据测试频率和团队协作方式选择合适的 Mac 租赁方案。重点不是单纯追求一台“能打开 Xcode”的机器,而是确认它能否长期保留项目依赖、模拟器数据、签名环境和测试结果。
05发布前按负责人角色完成最后验收
独立开发者:确认新增字符串没有静默遗漏
单人项目最常见的问题不是完全没有本地化,而是某次提交新增了一个错误提示、弹窗标题或设置项,却没有进入预期的 String Catalog。提交检查可以先比较目录变化,再运行一条覆盖核心路径的多语言 UI 测试。
如果文本来自普通 Swift、UIKit 或 AppKit 代码,应优先检查本地化 API;如果来自 SwiftUI,则要确认它确实属于用户可见的本地化字符串,而不是被拼接、包装或放在不会被构建扫描的路径中。
存量项目维护者:确认迁移没有造成重复和回退
迁移旧版 strings 或 stringsdict 时,应保留可回退的提交边界。每次只迁移一个模块,完成构建、运行、截图和资源检查后再合并。
如果导入翻译后出现警告,应查看 Xcode 的差异和问题视图。不要直接覆盖旧文件,因为重复 key、错误 Table 名称和 Target 资源归属问题,往往需要回到具体模块处理。
出海团队:把缺陷分成三个等级
发布负责人可以按下面方式处理结果:
- 阻断发布:关键语言缺失、购买或登录流程无法使用、Archive 缺少目标语言资源;
- 修复后重跑:核心页面截断、地区格式错误、复数显示不正确、RTL 布局错位;
- 记录后跟进:非核心页面的措辞优化、截图标注问题或不影响操作的轻微间距差异。
最终结论应明确写成“继续发布”“修复后重跑”或“回退本地化改动”,并保存对应的测试结果、截图、导出目录和 Archive 检查记录。这样下一次回归才有可比较的基线。
06常见问题:把搜索意图落到执行细节
如何确认 String Catalog 里没有漏掉新的文本?
先使用可本地化 API,并通过 Xcode Build 更新 String Catalog;SwiftUI 中的 LocalizedStringKey 通常会被自动发现,但普通 Swift、UIKit 或 AppKit 文本仍需使用对应的本地化初始化方式。随后用代表性页面运行 UI 测试,并检查生成的目录、运行界面和最终 Bundle,不能只看编辑器里的翻译百分比。
怎样为多个语言和地区复用同一批 iOS 测试?
在 Test Plan 中为实际支持的语言和地区建立配置,分别设置 Application Language 与 Application Region,再运行同一组核心 UI 测试。矩阵应优先覆盖真实市场、复数规则、货币日期格式、从右到左布局和关键设备尺寸,不建议机械组合所有语言与模拟器。
String Catalog 适合接入 CI 做自动校验吗?
可以,但持续集成不应只检查文件是否存在。可以将字符串导出、指定语言测试、UI 测试、截图收集和 Archive 资源检查拆成独立任务,并用 xcodebuild、Test Plan 与测试结果文件保存证据;需要图形界面的模拟器测试时,还要提前验证远程 Mac 的登录会话。
在远程 Mac 上执行多语言界面测试要准备什么?
先通过 SSH 将代码、依赖和签名环境准备好,再由远程 Mac 执行指定 Scheme 或 Test Plan。每种语言配置独立保存测试结果、截图和日志;如果任务依赖模拟器图形会话,就不能把它当作普通无界面脚本运行,还要测试断线、重启和重跑后的结果是否一致。
发布前怎样判断本地化验收是否真正完成?
至少检查新增字符串是否被提取、翻译状态是否完整、复数和插值是否正确、文本是否截断、日期货币数字是否符合地区、RTL 布局是否可用,以及最终 Archive 是否包含预期语言资源。缺失翻译、界面问题和基础设施失败应分级处理,分别决定继续发布、修复后重跑或回退改动。
07让 String Catalog 多语言测试成为发布门禁
真正稳定的自动化流程,不是把所有语言一次性塞进一个巨大任务,而是让每个阶段都能单独回答一个问题:字符串是否提取、翻译是否可用、界面是否可操作、截图是否可复核、产物是否完整。
如果当前方案依赖开发者本地 Mac 手动切换语言,常见缺点是环境无法长期在线、模拟器和 Xcode 资源会占用本地磁盘、测试结果容易散落在个人电脑中,而且多人协作时很难复现同一套语言地区配置。对于需要持续执行的多语言 UI 测试,把流程迁移到 NUKCLOUD 的远程 Mac,可以让 Xcode、Test Plan、模拟器和结果归档保留在一个可重复使用的环境中;但如果项目长期重度依赖实体 iPhone、专用外设或本地硬件调试,仍应保留本地 Mac 与真机作为主要验收设备。
当语言地区矩阵已经确定,下一步应检查远程主机是否能稳定保留构建依赖、签名环境和测试证据,再结合任务频率选择按需或持续使用的 NUKCLOUD Mac 方案。