Тестування локалізації мобільного додатку
Кнопка «Зареєструватися» на німецькій стала «Registrieren» та вийшла за межи UIButton — дизайнер не врахував, що німецька у середньому довша від російської на 35%. Або арабський RTL-текст перемішався з LTR-числами та виглядає як мусір. Це класика локалізаційного тестування, яку автотесты на англійській ніколи не поймуть.
Найчастіші проблеми
Хардкод строк. У Xcode localizedString(forKey:table:bundle:) не викликали — замість цього label.text = "Welcome" прямо у коді. Інструмент для пошуку: genstrings або SwiftLint правило no_direct_string_use (кастомне). На Android аналогічно — строки у strings.xml vs inline у XML-лейаутах vs конкатенація у Kotlin.
Форматування дат, чисел, валюти. DateFormatter без явного locale використовує системну локаль користувача, але NumberFormatter або просто String(format: "%.2f", price) — ні. Американський формат 1,234.56 у німецькій локалі повинен бути 1.234,56. Помилки такого роду не ломають UI, але виглядають непрофесійно.
Направлення тексту (BiDi). У арабській та іврит-локалі layoutDirection = RTL. Іконки «назад/вперед» міняються місцями, padding та margin повинні бути дзеркальними. На iOS semanticContentAttribute = .forceRightToLeft на рівні view hierarchy. На Android — android:supportsRtl="true" у манифесті та layoutDirection="locale" у layout-файлах. Якщо хоча б одна кастомна view рисує текст через Canvas.drawText без урахування RTL — буде баг.
Інструменти та підхід
Pseudolocalization — перший та найдешевший тест. Замінюємо усі строки псевдолокалізованою версією: додаємо акценти до букв та видовжуємо строки на 30–40% ([Ñéṁö Ŝţŕïñĝ!!!!!]). Це виявляє усі обрізані строки та хардкод до того, як ви заплатили перекладачу.
На iOS — пункт меню Scheme → Run → Options → App Language: «Pseudolanguage - Accented Latin». На Android — LocaleList.setDefault(Locale("ar")) у Application.onCreate для тестування RTL, або псевдолокаль en-XA через adb:
adb shell settings put global locale_overlay en-XA
Скриншот-тестування по локалям. Paparazzi (Android) або SnapshotTesting (iOS) дозволяють прогнати один тест з набором локалей:
@Test fun allLocales() {
for (locale in listOf("en", "de", "ar", "ja", "ru")) {
paparazzi.snapshot(locale = locale) {
RegistrationScreen()
}
}
}
Кожний прогон CI генерує скриншоти — рецензент видит різницю візуально. Ловит обрізані кнопки автоматично.
Ручне тестування з нативним носієм. Для семантики немає замінника. Машинний переклад може дати грамотно верний, але контекстуально дивний текст. «Натисніть тут» на японському звучить грубо — потрібно お進みください. Це не автоматизується.
| Перевірка | Інструмент | Коли |
|---|---|---|
| Хардкод строк | SwiftLint / Android Lint | У CI на кожен PR |
| Обрізка UI | Pseudolocalization | При розробці |
| Скриншоти по локалям | Paparazzi / SnapshotTesting | У CI |
| RTL layout | Device/emulator з арабською локаллю | Перед релізом |
| Форматування чисел та дат | Unit-тесты з конкретними локалями | При розробці |
| Семантика перекладу | Нативний носій | Перед релізом |
Процес роботи
Аудит поточних локалей — скільки підтримується, есть ли RTL. Налаштування pseudolocalization у Scheme/build config. Додавання скриншот-тестів по ключовим екранам з набором локалей. Ручне тестування найскладніших мов (арабський, японський, німецький). Список знайдених дефектів з відтворенням.
Строки — 2–4 дні на проект з 3–5 локалями. RTL-локалі додають 1–2 дні, якщо layout не готувався до RTL з нуля.







