Xcode 7 UITests具有本地化UI

net*_*000 32 ios swift xcode7 xcode-ui-testing

在我的应用程序中,我正在使用NSLocalizedString本地化我的应用程序.现在我想切换到UITests和这样的测试代码:

[tabBarsQuery.buttons["particiants"] tap];
Run Code Online (Sandbox Code Playgroud)

这适用于英语,但不适用于其他语言.

[tabBarsQuery.buttons[NSLocalizedString("PARTICIPANTS",comment:nil)] tap];
Run Code Online (Sandbox Code Playgroud)

失败 - 可能是因为Localizable.strings在另一个包中.如何测试本地化应用?

Joe*_*tti 24

选项1:设置默认语言

为UI测试创建新方案并设置默认应用程序语言.这会将应用程序锁定到一个本地化文件中,以便您可以编写该语言的所有测试.

从产品 - >方案 - >管理方案或设置选项⌘⇧,.然后选择"选项"选项卡并设置语言.

Xcode  - 设置默认应用程序语言

优点:简单,一次性改变.

缺点:不能用于创建带快照的本地化屏幕截图(一种通过UI测试运行您的应用程序并在此过程中生成App Store屏幕截图的工具).

选项2:-accessibilityIdentifier用于本地化字符串

而不是通过显示的文本或值访问项目,请使用accessibilityIdentifier.这是由UI测试框架读取的,但从未向用户显示或读取(即使打开了辅助功能).在旧的UIAutomation文档中,Apple提到将此用于开发人员功能,这就像一个很好的用例.

然后,您可以使用本地化版本继续设置accessibilityLabelaccessibilityValue正常一样.

优点:可用于更通用的解决方案,例如采用自动截图.

缺点:可能需要更多工作来更改您需要"未定位"的每个标签进行测试.

  • 请参阅我的编辑,以获得第二个使用`accessibilityIdentifier`的选项. (5认同)
  • 我不想将我的应用程序锁定为一种语言,因为我想使用https://github.com/fastlane/snapshot创建本地化的屏幕截图 (3认同)

Vol*_*iuk 13

您可以重新使用您的项目本地化套件!

当您测试消息框行为时,您需要确切地知道刚出现的消息框.您需要在构建阶段从其他方案复制本地化.

在UI测试目标 - >构建阶段 - >复制包资源中,添加所需的本地化文件(例如Localizable.strings).

添加类似于以下的功能:

func localizedString(key:String) -> String {
/*1*/ let localizationBundle = NSBundle(path: NSBundle(forClass: /*2 UITestsClass*/.self).pathForResource(deviceLanguage, ofType: "lproj")!) 
/*3*/ let result = NSLocalizedString(key, bundle:localizationBundle!, comment: "") // 
    return result
}

/*1 Gets correct bundle for the localization file, see here: http://stackoverflow.com/questions/33086266/cant-get-access-to-string-localizations-in-ui-test-xcode-7 */
/*2 Replace this with a class from your UI Tests 
/*3 Gets the localized string from the bundle */
Run Code Online (Sandbox Code Playgroud)

然后在你的代码中你可以使用app.buttons [localizedString("localized.string.key")]

完整文章在这里:https://github.com/fastlane-old/snapshot/issues/321#issuecomment-159660882


Sea*_*anR 13

我想实际测试UI功能的内容而不仅仅是它们的存在,因此设置默认语言或使用辅助功能标识符是不合适的.

这建立在Volodymyrmatsoftware的答案之上.然而,他们的答案依赖于deviceLanguage需要明确设置的内容SnapshotHelper.此解决方案动态获取设备正在使用的实际支持语言.

  1. Localizable.strings文件添加到UITest目标.
  2. 将以下代码添加到您的UITest目标:

    var currentLanguage: (langCode: String, localeCode: String)? {
        let currentLocale = Locale(identifier: Locale.preferredLanguages.first!)
        guard let langCode = currentLocale.languageCode else {
            return nil
        }
        var localeCode = langCode
        if let scriptCode = currentLocale.scriptCode {
            localeCode = "\(langCode)-\(scriptCode)"
        } else if let regionCode = currentLocale.regionCode {
            localeCode = "\(langCode)-\(regionCode)"
        }
        return (langCode, localeCode)
    }
    
    func localizedString(_ key: String) -> String {
        let testBundle = Bundle(for: /* a class in your test bundle */.self)
        if let currentLanguage = currentLanguage,
            let testBundlePath = testBundle.path(forResource: currentLanguage.localeCode, ofType: "lproj") ?? testBundle.path(forResource: currentLanguage.langCode, ofType: "lproj"),
            let localizedBundle = Bundle(path: testBundlePath)
        {
            return NSLocalizedString(key, bundle: localizedBundle, comment: "")
        }
        return "?"
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 访问方法 localizedString(key)

对于那些带有脚本代码的语言,localeCode将是langCode-scriptCode(例如zh-Hans).否则localeCode将是langCode-regionCode(例如pt-BR).第testBundle一个尝试解决lproj localeCode,然后回到just langCode.

如果它仍然无法获得捆绑,则返回"?" 对于字符串,所以它将失败任何寻找特定字符串的UI测试.

  • 这对我的`localizable.strings`很有用!但是,我似乎无法使用我的Storyboard字符串文件.你知道我怎么解决这个问题吗?构建时,故事板字符串不会转到最终的lproj文件夹吗? (2认同)

Vla*_*yuk 6

到目前为止,对我来说最简单可靠的方法是使用elementBoundByIndex()引用元素,如下所示:

    let app = XCUIApplication()
    let tabBar = app.tabBars
    tabBar.buttons.elementBoundByIndex(2).tap()
    app.navigationBars.buttons.elementBoundByIndex(0).tap()
    app.tables.cells.elementBoundByIndex(2).tap()
    app.tables.elementBoundByIndex(1).cells.elementBoundByIndex(0).tap()
Run Code Online (Sandbox Code Playgroud)

您可以猜测/试验此值并找到所需的元素.

  • 无论出于何种原因,我都会重新安排布局.测试将失败并且每次都会计算所有受影响的索引.抱歉,但不,这甚至与`accessibilityIdentifier`的可靠性无关.为了使这个可行,你至少应该将这些元素分配给有意义的变量名 (3认同)