How do you test internationalisation before translations exist: pseudolanguages, launch arguments, text expansion and the export and import workflow?

24.4.1 · L3 · Interview

Predict first

A process is launched with -AppleLanguages "(de)" -AppleLocale de_DE. What do its preferred language and locale report?

// === main.swift ===
import Foundation
print(Locale.preferredLanguages.first ?? "-", Locale.current.identifier)
  • de de_DE
  • en en_US always
  • The arguments are ignored

Predict first

Which xcodebuild options exist for exporting and importing localisations?

// === dummy ===
  • -exportLocalizations and -importLocalizations (with -exportLanguage and -localizationPath)
  • None: use the GUI only
  • Only -importLocalizations

Mental model. Pseudo-localisation is a stress test with a fake language: if the building survives a rubber-stamped alphabet that is twice as long, it will survive real ones.

You do not need translators to find most internationalisation bugs. Xcode’s scheme (Run ▸ Options ▸ App Language) offers pseudolanguages: the Double-Length one repeats strings to simulate text expansion (German and Finnish are often 30% to 50% longer than English, and some strings far more), the Accented one adds diacritics so you can spot any string you forgot to localise, the Bounded String one wraps text in brackets so truncation shows, and the Right-to-Left one mirrors the layout (see the right-to-left question). Run the app in these and look for clipped text, fixed-width buttons, overlapping views and any text that did not change (hard-coded English). You can also set the language and region without touching the device’s settings: the launch arguments -AppleLanguages "(de)" and -AppleLocale de_DE in the scheme, in a UI test’s launchArguments or in a test plan’s language and region configuration run the same app in another locale. The check below launches a process with those arguments and it reports de and de_DE; other documented flags such as -NSDoubleLocalizedStrings YES and -NSShowNonLocalizedStrings YES highlight expansion and missing localisations.

Remember that language and region are separate (Q82, Q111): a user can run English text with German formatting, so test combinations, not only matching pairs. For translation use the export and import workflow: Xcode exports a localisation catalog (.xcloc) per language for translators and imports it back, and the command-line options xcodebuild -exportLocalizations and -importLocalizations do the same for automation (the check lists them). Keep strings in a catalog with comments that explain context (“Button to send a message” disambiguates “Post”), avoid concatenating sentence fragments (word order differs, Q110), avoid text in images, and design for expansion up front: flexible widths, wrapping, no truncation of critical text. Add a CI step or UI test that launches in a long-text pseudolanguage and an RTL language and takes screenshots, so layout regressions show up automatically.

Launch arguments override the language and region for that process, which is how schemes, test plans and UI tests change locale.

The command line mirrors the Editor ▸ Export and Import Localizations workflow, so it can be scripted.

Common traps

  • Testing only English and one translation. Layout bugs appear with long text and RTL, not with a language you happen to speak.
  • Fixed-width labels and buttons. A longer translation clips; use flexible constraints and wrapping.

They might follow up with

  • How do you launch in another language without changing the device? The -AppleLanguages and -AppleLocale launch arguments, or the scheme or test plan setting.
  • How do you give translators context? Comments on each string in the catalog, and screenshots when possible.

Related questions

  • 24.3.1 How do you support right-to-left languages: leading and trailing, semantic content attributes, flipping…
  • 24.3.2 How is bidirectional text handled, why should you isolate user-generated strings, and how do different…
  • 24.4.2 What changes by locale beyond strings: sorting and searching, the first day of the week, calendars, names and…
  • 2.2.6 What is a Locale, and how is it different from the user’s language?
  • 2.6.3 How do you localise strings: Localizable.strings, string catalogs, String(localized:)?
  • 22.4.2 What makes a test non-deterministic, and how do you control time zones, locales, randomness, UUIDs and the…

What changes by locale beyond strings: sorting and searching, the… →