In my App I'm using NSLocalizedString
to localize my app. Now I want to switch to UITests
and have Testcode like this:
[tabBarsQuery.buttons["particiants"] tap];
This works for English but fails for other languages.
[tabBarsQuery.buttons[NSLocalizedString("PARTICIPANTS",comment:nil)] tap];
Fails - probably because Localizable.strings is in another bundle. How can I test a localized app?
I wanted to actually test the content of UI features and not just their existence, so setting a default language or using the accessibility identifiers wouldn't suit.
This builds on Volodymyr's and matsoftware's answers. However their answers rely on deviceLanguage
which needs to be explicitly set in SnapshotHelper
. This solution dynamically gets the actual supported language the device is using.
Localizable.strings
files to your UITest target.Add the following code to your UITest target:
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 "?"
}
Access the method by localizedString(key)
For those languages with a script code, the localeCode
will be langCode-scriptCode
(for example, zh-Hans
). Otherwise the localeCode
will be langCode-regionCode
(for example, pt-BR
). The testBundle
first tries to resolve the lproj by localeCode
, then falls back to just langCode
.
If it still can't get the bundle, it returns "?" for the string, so it will fail any UI tests that look for specific strings.