Xcode 7 Uitesty ze zlokalizowanym interfejsem użytkownika
W mojej aplikacji używam NSLocalizedString
, aby zlokalizować moją aplikację. Teraz chcę przełączyć się na UITests
i habe Testcode Tak:
[tabBarsQuery.buttons["particiants"] tap];
To działa w języku Angielskim, ale zawodzi w innych językach.
[tabBarsQuery.buttons[NSLocalizedString("PARTICIPANTS",comment:nil)] tap];
Fails-prawdopodobnie dlatego, że Localizable.struny są w innym pakiecie. Jak Mogę przetestować zlokalizowaną aplikację?
9 answers
Chciałem przetestować zawartość funkcji interfejsu użytkownika, a nie tylko ich istnienie, więc ustawienie domyślnego języka lub użycie identyfikatorów dostępności Nie pasowałoby.
To buduje się na odpowiedziach Wołodymyra i matsoftware. Jednak ich odpowiedzi opierają się na deviceLanguage
, która musi być jawnie ustawiona w SnapshotHelper
. To rozwiązanie dynamicznie pobiera aktualnie obsługiwany język, którego używa urządzenie.
- Dodaj pliki
Localizable.strings
do swojego Uitestu cel. -
Dodaj następujący kod do celu 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 "?" }
Dostęp do metody przez
localizedString(key)
Dla tych języków z kodem skryptu, localeCode
będzie langCode-scriptCode
(na przykład, zh-Hans
). W przeciwnym razie {[5] } będzie langCode-regionCode
(na przykład pt-BR
). {[11] } najpierw próbuje rozwiązać lproj przez localeCode
, a następnie wraca do tylko langCode
.
Jeśli nadal nie może dostać pakietu, to wraca"?"Dla ciągu, więc nie zda żadnych testów UI, które poszukaj konkretnych strun.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:51
Opcja 1: Ustaw domyślny język
Utwórz nowy schemat testowania interfejsu użytkownika i Ustaw domyślny język aplikacji. Spowoduje to zablokowanie aplikacji w jednym zlokalizowanym pliku, dzięki czemu można zapisać wszystkie testy dla tego języka.
Ustaw opcję Z Product -> Scheme - > Manage Schemes lub ⌘⇧,. Następnie wybierz kartę Opcje i ustaw język.
Plusy : prosta, Jednorazowa zmiana.
Cons: nie może być użyty do twórz zlokalizowane zrzuty ekranu za pomocą migawki (narzędzia, które uruchamia aplikację za pomocą testowania interfejsu użytkownika i generuje zrzuty ekranu ze sklepu App Store).
Opcja 2: Użyj -accessibilityIdentifier
dla zlokalizowanych łańcuchów
Zamiast uzyskiwania dostępu do elementów za pomocą wyświetlonego tekstu lub wartości, użyj accessibilityIdentifier
. Jest to odczytywane przez interfejs Testing framework, ale nigdy nie pokazywane ani odczytywane użytkownikom (nawet przy włączonej dostępności). W starej dokumentacji UIAutomation Apple wspomina o używaniu tego dla funkcji programisty, które to szwy jak dobry przypadek użycia.
Możesz kontynuować ustawianie accessibilityLabel
i accessibilityValue
Jak zwykle, z zlokalizowanymi wersjami.
Plusy: może być używany do bardziej ogólnych rozwiązań, takich jak robienie automatycznych zrzutów ekranu.
Cons: może wymagać więcej pracy, zmieniając każdą etykietę, której potrzebujesz "unlocalized" do testowania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-09 17:44:27
MOŻESZ PONOWNIE WYKORZYSTAĆ PAKIETY LOKALIZACYJNE PROJEKTU!
Kiedy testujesz zachowanie skrzynek wiadomości, musisz dokładnie wiedzieć, które okno wiadomości właśnie się pojawiło. Musisz skopiować lokalizację z innego schematu podczas fazy budowania.
W interfejsie testowym target -> fazy budowania - > Kopiuj zasoby pakietu, dodaj potrzebne pliki lokalizacyjne (np. Localizable.struny).
Dodaj funkcję podobną do następującej:
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 */
Wtedy w kodzie możesz użyć app.przyciski [localizedString ("localized.sznurek.klucz")]
Pełny artykuł jest tutaj: https://github.com/fastlane-old/snapshot/issues/321#issuecomment-159660882
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 22:08:28
Jak dotąd najprostszym i niezawodnym sposobem jest odwoływanie się do elementów za pomocą elementBoundByIndex() Tak:
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()
Możesz zgadywać / eksperymentować z tymi wartościami i znaleźć potrzebne elementy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-18 18:17:34
ODPOWIEDŹ Wołodymyra bardzo mi pomogła, ale może się nie udać, jeśli nazwa folderu pakietu lokalizacyjnego różni się od nazwy urządzenia ustawionego w Migawce. Ten fragment działa dobrze dla mnie w Swift 3.0 i z językami takimi jak włoski(gdzie obecne ustawienia regionalne to "it", ale język urządzenia to "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
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 18:09:05
Jeśli robisz to w celu uruchomienia migawki (a nie rzeczywistego testowania interfejsu użytkownika), to uważam, że najprostszym rozwiązaniem jest oszukiwanie i używanie HSTestingBackchannel
Jest to narzędzie, które napisałem, które pozwala na wysyłanie powiadomień z klasy UITesting do aplikacji. Następnie piszesz kod w aplikacji, który odpowiada bezpośrednio na powiadomienia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-05 18:04:35
Oprócz odpowiedzi Joe możesz również wymusić język dla testów interfejsu użytkownika bezpośrednio w kodzie testowym bez edytowania takiego schematu:
- (void)setUp
{
[super setUp];
self.continueAfterFailure = NO;
XCUIApplication *app = [[XCUIApplication alloc] init];
app.launchArguments = @[@"-AppleLanguages", @"(en)", @"-AppleLocale", @"en_EN"];
[app launch];
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-26 14:39:45
Odpowiedź SeanR jest świetna (+1), ale jest niewielka poprawa:
Jeśli używasz lokalizacji bazowej, twój Localizable.strings
może nie być zlokalizowany w Twoim języku bazowym. Nie jest to konieczne, ponieważ język bazowy byłby używany w tym przypadku. Jeśli tak, Funkcja SeanR localizedString
zwróci „?“
.
Poniższa rozszerzona wersja sprawdza dodatkowo język podstawowy i zwraca zlokalizowany ciąg znaków w języku bazowym:
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 "?"
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-31 21:31:56
Dla funkcji migawki fastlane, SnapshotHelper.swift
uruchamia aplikację z tymi argumentami. Tak więc interpretując te wartości, To rozwiązanie jest deterministyczne i byłem w stanie stworzyć poprawne migawki dla wielu języków: {]}
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 ""
}
Hope this helps
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-16 12:32:58