Xcode UI 测试、开发语言、后备翻译和 CI 服务器

Xcode UI tests, development language, fallback translation and CI servers

以下场景:

我有一个 iOS 项目,它自动获取单元并 UI 在 CI 服务器上的每个 git 推送上进行测试(CircleCI ).测试使用 fastlane 执行,它也用于自动为 App Store 创建屏幕截图。

现在,我的项目被翻译成多种语言。我希望 fastlane 适用于所有语言(以便能够截取屏幕截图),所以我将 UI 测试从这样的内容更改为:

app.navigationBars.buttons["Confirm"].tap()

let buttonTitle = NSLocalizedString("navbar.confirm", comment: "")   
app.navigationBars.buttons[buttonTitle].tap()

我认为这会成功,但事实并非如此。我不知道模拟器在 CircleCI 中是如何配置的,但是 UI 测试现在失败了

[00:46:34]: ▸ testDashboard, No matches found for Find: Elements matching predicate '"navbar.confirm" IN identifiers' from input {(

所以出于某种原因,使用 CFBundleDevelopmentRegion 设置的回退语言没有得到尊重,可能是因为该语言不在包的 preferredLanguages 列表中。这本身就是一个问题,因为我不希望在任何情况下都为最终用户显示密钥。我想确保这永远不会发生。

所以我试图通过为 NSLocalizedString 编写一个包装器来修复这个问题,该包装器检查 NSLocalizedString(..) returns 密钥是否加载默认值(en ) 捆绑并以这种方式本地化字符串。

但是 您似乎无法在 UI 测试中加载另一个包。测试将崩溃并失败。所以我不能使用这个解决方法。

我是否只是忽略了一些明显的解决方案?我不可能是唯一遇到这个问题的人,对吧?有什么提示吗?

当您使用 NSLocalizedString("navbar.confirm", comment: "") 时,系统会尝试从主包中的字符串文件中检索该键的值。

主包在 运行 UITest 时不起作用,因为它为您提供 UITest Runner App 的包而不是 UITest 包。

为了能够在 UITest 中使用 NSLocalizedString 你必须做两件事:

1.将您的 Localizable.strings 文件添加到您的 UITest 目标

2。通过 UITest 包访问文件(您可以为此使用一些辅助方法):

func localized(_ key: String) -> String {
    let uiTestBundle = Bundle(for: AClassFromYourUITests.self)
    return NSLocalizedString(key, bundle: uiTestBundle, comment: "")
}

您可以使用 UITest 中的任何 class 来访问 UITest 包。

现在您可以像这样在 UITest 中使用 NSLocalizedString:

app.navigationBars.buttons[localized("navbar.confirm")].tap()

我刚才写了一些关于这个的blog post,如果你有兴趣了解更多细节。

在您的 UI 元素上设置可访问性标识符,并在您的测试中使用这些标识符进行查询,而不是使用本地化的字符串值。这将使您的测试与语言无关,并且不需要 fiddle 访问不同的包。

有关如何设置和使用辅助功能标识符的示例,请参阅