做多语言 App 的你肯定遇到过这个场景:写了一套 Maestro 的 UI 自动化流程,想在德语、日语、阿拉伯语下各跑一遍,截几张本地化截图或做个烟雾测试。文档上只写了 `--device-locale` 这个启动设备时的参数,但实际操作起来坑不少——最坑的是流程全绿,截图却全英文,毫无提示。这篇文章把 Maestro 多语言运行的正确姿势和四个隐蔽陷阱讲透了,我在自己的模拟器上复现了作者说的每一个问题,结论都一致。

先说官方文档的路线。Maestro 官方 locale 页面明确说,流程内部(launchApp 或 config.yaml)没有定义 locale 的地方,只能用 `maestro start-device --platform android --device-locale fr_FR` 启动一个指定语言的设备,再用 `maestro test --include-tags french .maestro/` 配合 tag 运行。这样确实有效,但代价是整个设备都变成目标语言,要跑 N 种语言就得来回重启设备或起 N 个设备,而且语言配置散落在 shell 脚本和 tag 里,流程文件本身反而管不着。

作者给出的替代方案是只改单 App 的语言,设备保持原样。iOS 上利用 launchApp 的 arguments 参数:iOS 会读 `AppleLanguages` 和 `AppleLocale` 这两个启动参数,所以一个流程可以用变量控制语言。关键代码是这样的:

```yaml

appId: com.example.myapp

launchApp:

clearState: true

arguments:

AppleLanguages: "(${APP_LANG})"

AppleLocale: "${APP_LOCALE}"

tapOn:

id: onboarding_next

takeScreenshot: shots/${APP_LANG}/02_onboarding

```

注意 `tapOn` 和 `takeScreenshot` 的顺序,作者在 Maestro 2.0.10、iOS 26.4 模拟器上实测:launchApp 后直接截图,4 次有 4 次截的是 iOS 主屏幕而不是 App,加一个 `extendedWaitUntil` 等待界面元素出现后再截,才能拿到 App 画面。这是容易被忽略的细节。

运行方式也很简单:`for pair in en:en_US de:de_DE ja:ja_JP; do maestro --device "$UDID" test -e APP_LANG="${pair%%:*}" -e APP_LOCALE="${pair##*:}" flow.yaml; done`,每条命令用 `-e` 传变量,一次跑一个语言。

Android 侧,Android 13(API 33)起支持按应用设置语言,不用改系统语言,用 adb 命令搞定:

```bash

adb -s emulator-5554 shell pm clear com.example.myapp

adb -s emulator-5554 shell cmd locale set-app-locales com.example.myapp --locales de

```

然后跑同一个流程,但要注意不能带 `clearState`(原因见下文的陷阱 3)。为了保持一份流程同时支持两个平台,可以用 `runFlow` 包一层,`when: platform: iOS` 和 `when: platform: Android` 分别处理。

还有一个常见问题:流程里写 `tapOn: "Next"` 在德语下就失效了。两种解法:用 `id` 定位(iOS 的 accessibility identifier、Android 的 resource id),id 不随语言变化;或者为每种语言写对应文案。如果 App 里所有可点元素都有 id,那这篇文章后半部分基本可以不用看了。

文章重点列了四个会让你莫名其妙拿到英文截图的陷阱,作者都亲测过:

**陷阱 1:流程头部的默认值会覆盖命令行参数。** 如果流程文件顶部写了 `env: { LOCALE: en }` 作为默认值,后面用 `-e APP_LANG=de` 传参也不生效,还是跑出英文。作者复现的是 Maestro 2.0.10 上 iOS 的表现,有人提过 PR #216 修复类似问题,但结论很简单:千万别在 header 里给语言变量设默认值,只用 `-e` 传,并且每跑完一个语言先看第一张截图确认。

**陷阱 2:`-e` 必须放在 `test` 后面。** 命令顺序是 `maestro --device X test -e KEY=VALUE flow.yaml`,如果写成 `maestro -e APP_LANG=de test flow.yaml`,会拿到 `Unknown options: '-e', 'APP_LANG=de'` 和退出码 2,但如果你脚本忽略退出码,看起来还是

Manuel
Manuel
阅读原文 → 返回 AI 技术文档

内容与图片版权归原作者所有 · 原文: https://dev.to/n0loman/run-one-maestro-flow-in-every-language-ios-launch-arguments-android-per-app-locales-and-the-traps-2mk2