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

Posted

技术标签:

【中文标题】Xcode UI 测试、开发语言、回退翻译和 CI 服务器【英文标题】:Xcode UI tests, development language, fallback translation and CI servers 【发布时间】:2017-10-09 18:29:06 【问题描述】:

以下场景:

我有一个 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 测试中加载另一个包。测试将崩溃并失败。所以我不能使用这个解决方法。

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

【问题讨论】:

【参考方案1】:

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

主包在运行 UITests 时不起作用,因为它为您提供 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: "")

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

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

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

如果您有兴趣了解更多细节,我不久前写了一点blog post。

【讨论】:

【参考方案2】:

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

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

【讨论】:

这其实是更好的处事方式。我想知道这是否可能,但我只是偶然发现了可访问性标签,而不是标识符。感谢分享!

以上是关于Xcode UI 测试、开发语言、回退翻译和 CI 服务器的主要内容,如果未能解决你的问题,请参考以下文章

Xcode UI 测试 - 当测试套件中的任何给定测试失败时停止测试?

什么是 CI/CD?(翻译)

Xcode 7 UI 测试初窥

iOS持续集成大比拼:Xcode ServerJenkinsTravis和fastlane

Django 模型翻译查询回退

在 CI 中使用存储权限进行 Android UI 测试