Dans mon application, j'utilise NSLocalizedString
pour localiser mon application. Maintenant, je veux passer à UITests
et avoir Testcode comme ceci:
[tabBarsQuery.buttons["particiants"] tap];
Cela fonctionne pour l'anglais mais échoue pour les autres langues.
[tabBarsQuery.buttons[NSLocalizedString("PARTICIPANTS",comment:nil)] tap];
Echec - probablement parce que Localizable.strings est dans un autre lot. Comment puis-je tester une application localisée?
Je voulais réellement tester le contenu des fonctionnalités de l'interface utilisateur et pas seulement leur existence, donc définir une langue par défaut ou utiliser les identificateurs d'accessibilité ne conviendrait pas.
Cela s'appuie sur les réponses de Volodymyr et matsoftware . Cependant, leurs réponses reposent sur deviceLanguage
qui doit être explicitement défini dans SnapshotHelper
. Cette solution récupère de manière dynamique la langue actuellement prise en charge par le périphérique.
Localizable.strings
à votre cible UITest.Ajoutez le code suivant à votre cible 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 "?"
}
Accéder à la méthode par localizedString(key)
Pour les langues avec un code de script, la localeCode
sera langCode-scriptCode
(par exemple, zh-Hans
). Sinon, la localeCode
sera langCode-regionCode
(par exemple, pt-BR
). testBundle
tente d’abord de résoudre le problème de lproj de localeCode
, puis retombe à langCode
.
S'il ne peut toujours pas obtenir le paquet, il retourne "?" pour la chaîne, il échouera donc tous les tests d'interface utilisateur qui recherchent des chaînes spécifiques.
Voir plus de détails Schéma pour les essais de formation de stagiaires et pour les célébrations du festival. Voir l'appli dans les dates les plus récentes, les tests de qualité pour les tests de performance, les tests de sécurité.
Stellen Sie die Option unter Produkt -> Schema -> Schemas verwalten oder ein⌘⇧,. En savoir plus sur les options de commande et de retour pour les ordinateurs.
Vorteile : Einfache, einmalige Änderung.
Nachteile : Captures d'écran capturées Captures d'écran mit Schnappschuss (outil simple, avec application supplémentaire et tests UI-test ausgeführt und der App Store généré par le Web) verwendet werden Screenshots auf dem Weg).
-accessibilityIdentifier
für lokalisierte ZeichenfolgenVerwenden Sie accessibilityIdentifier
, anstatt über den angezeigten Texte ou Signification du contenu. Meurs wird vom UI Testing-Framework gelesen, aber niemals Benutzern angezeigt oder vorgelesen (Auch bei aktivierter Eingabehilfe). Dans tous les domaines, Apple meurt pour le monde des affaires, a été tuée par le gouvernement.
Anschließend können Sie accessibilityLabel
und accessibilityValue
wie gewohnt mit den lokalisierten Versionen festlegen.
Vorteile : Cliquez ici pour afficher le texte intégral, cliquez ici. B. für automatisierte Screenshots.
Nachteile : Mes connaissances, mes références, ses notes, ses notes, ses notes, ses notes, ses notes.
VOUS POUVEZ RÉUTILISER VOS GROUPES DE LOCALISATION DE PROJET!
Lorsque vous testez le comportement des boîtes de message, vous devez savoir exactement quelle boîte de message vient d'apparaître. Vous devez copier votre localisation à partir d'un autre schéma pendant la phase de construction.
Dans votre cible Tests d’interface utilisateur -> Phases de construction -> Copier les ressources d’un ensemble, ajoutez les fichiers de localisation nécessaires (par exemple, Localizable.strings).
Ajoutez une fonction similaire à celle-ci:
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 */
Ensuite, dans votre code, vous pouvez utiliser app.buttons [localizedString ("localized.string.key")]
L'article complet est ici: https://github.com/fastlane-old/snapshot/issues/321#issuecomment-159660882
Jusqu'à présent, le moyen le plus simple et le plus fiable consiste à référencer des éléments avec elementBoundByIndex () Comme ceci:
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()
Vous pouvez deviner/expérimenter avec ces valeurs et trouver les éléments dont vous avez besoin.
La réponse de Volodymyr m'a beaucoup aidé, mais elle peut échouer si le nom du dossier de l'ensemble de localisation est différent de deviceLanguage défini dans Snapshot. Cet extrait fonctionne bien pour moi dans Swift 3.0 et dans des langues telles que l'italien (les paramètres régionaux sont "it", mais la langue de l'appareil est "it-IT").
func localizedString(key:String) -> String {
let languageBundlePath = Bundle(for: PlinthUITests.self).path(forResource: deviceLanguage, ofType: "lproj") ?? Bundle(for: PlinthUITests.self).path(forResource: NSLocale.current.languageCode!, ofType: "lproj")
let localizationBundle = Bundle(path: languageBundlePath!)
let result = NSLocalizedString(key, bundle:localizationBundle!, comment: "")
return result
}
Si vous faites cela dans le but d'exécuter Snapshot (plutôt que de tester l'interface utilisateur), la solution la plus simple est de tricher et d'utiliser HSTestingBackchannel
C'est un outil que j'ai écrit qui vous permet d'envoyer des notifications de la classe UITesting à l'application. Vous écrivez ensuite un code dans l'application qui répond directement aux notifications.
La réponse de SeanR est excellente (+1), mais il y a une amélioration mineure:
Si vous utilisez la localisation de base, il est possible que votre Localizable.strings
ne soit pas localisé dans votre langue de base. Ce n'est pas nécessaire car la langue de base serait utilisée dans ce cas. Si tel est le cas, la fonction localizedString
de SeanR renverra „?“
.
La version étendue ci-dessous vérifie également la langue de base et renvoie la chaîne localisée dans la langue de base:
func localizedString(_ key: String) -> String {
let testBundle = Bundle(for: ShopEasyUITests.self)
guard let currentLanguage = currentLanguage else { return "?" }
if let testBundlePath = testBundle.path(forResource: currentLanguage.localeCode, ofType: "lproj"),
let localizedBundle = Bundle(path: testBundlePath) {
return NSLocalizedString(key, bundle: localizedBundle, comment: "")
}
if let testBundlePath = testBundle.path(forResource: currentLanguage.langCode, ofType: "lproj"),
let localizedBundle = Bundle(path: testBundlePath) {
return NSLocalizedString(key, bundle: localizedBundle, comment: "")
}
if let testBundlePath = testBundle.path(forResource: "Base", ofType: "lproj"),
let localizedBundle = Bundle(path: testBundlePath) {
return NSLocalizedString(key, bundle: localizedBundle, comment: "")
}
return "?"
}
Solution Objective-C: Inspirée de la solution @Volodymyr Prysiazhniuk
- (NSString*)getLocalizedStringForKey :(NSString*)stringKey forUITestClass : (id) uiTestClass{
if (!stringKey || !uiTestClass){
return nil;
}
NSString *bundlePath = [[NSBundle bundleForClass: uiTestClass]bundlePath];
NSBundle* bundle = [NSBundle bundleWithPath:bundlePath];
NSString* localizedString = NSLocalizedStringWithDefaultValue(stringKey, nil, bundle, nil, nil);
return localizedString;
}
En plus de la réponse de Joe, vous pouvez également forcer le langage pour les tests d'interface utilisateur directement dans le code de test sans modifier un schéma comme celui-ci:
- (void)setUp
{
[super setUp];
self.continueAfterFailure = NO;
XCUIApplication *app = [[XCUIApplication alloc] init];
app.launchArguments = @[@"-AppleLanguages", @"(en)", @"-AppleLocale", @"en_EN"];
[app launch];
}
Pour la fonction d'instantané de fastlane, SnapshotHelper.Swift
lance l'application avec ces arguments. Donc, en interprétant ces valeurs, cette solution est déterministe et j'ai été capable de produire des instantanés corrects pour plusieurs langues:
func getLocale(str: String) -> String {
let start = str.index(str.startIndex, offsetBy: 1)
let end = str.index(start, offsetBy: 2)
let range = start..<end
var locale = str.substring(with: range)
if locale == "en" {
return "Base"
}
return locale
}
func localizedString(_ key: String) -> String {
print("app.launchArguments \(app.launchArguments)")
guard let localeArgIdx = app.launchArguments.index(of: "-AppleLocale") else {
return ""
}
if localeArgIdx >= app.launchArguments.count {
return ""
}
let str = app.launchArguments[localeArgIdx + 1]
let locale = getLocale(str: str)
let testBundle = Bundle(for: Snapshot.self)
if let testBundlePath = testBundle.path(forResource: locale, ofType: "lproj") ?? testBundle.path(forResource: locale, ofType: "lproj"),
let localizedBundle = Bundle(path: testBundlePath)
{
return NSLocalizedString(key, bundle: localizedBundle, comment: "")
}
return ""
}
J'espère que cela t'aides