0

以下场景:

我有一个 iOS 项目,它会在 CI 服务器 (CircleCI) 上的每次 git push 上自动获取单元和 UI 测试。测试使用 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,找不到匹配项:从输入 {(

因此,由于某种原因,CFBundleDevelopmentRegion不尊重后备语言集,可能是因为该语言不在preferredLanguages捆绑包的列表中。这本身就是一个问题,因为无论如何我都不希望为最终用户显示密钥。我想确保这永远不会发生。

所以我尝试通过编写一个包装器来解决这个问题NSLocalizedString,检查是否NSLocalizedString(..)返回密钥,如果是,则加载默认 ( en) 包并以这种方式本地化字符串。

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

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

4

2 回答 2

2

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

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

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

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

2. 通过 UITest 包访问文件(你可以使用一些辅助方法):

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

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

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

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

如果您对更多细节感兴趣,我不久前写了一篇关于此的小博客文章。

于 2017-10-09T20:16:05.853 回答
1

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

有关如何设置和使用可访问性标识符的示例,请参阅此答案。

于 2017-10-10T06:41:12.010 回答