Files
chromebox_10th_audio_driver/_bmad/gds/gametest/knowledge/localization-testing.md
2026-04-04 20:52:05 +08:00

9.3 KiB

Localization Testing Guide

Overview

Localization testing ensures games work correctly across languages, regions, and cultures. Beyond translation, it validates text display, cultural appropriateness, and regional compliance.

Test Categories

Linguistic Testing

Category Focus Examples
Translation accuracy Meaning preserved Idioms, game terminology
Grammar/spelling Language correctness Verb tense, punctuation
Consistency Same terms throughout "Health" vs "HP" vs "Life"
Context Meaning in game context Item names, skill descriptions

Functional Testing

Category Focus Examples
Text display Fits in UI Button labels, dialog boxes
Font support Characters render CJK, Cyrillic, Arabic
Text expansion Longer translations German is ~30% longer
RTL support Right-to-left languages Arabic, Hebrew layouts

Cultural Testing

Category Focus Examples
Cultural sensitivity Offensive content Gestures, symbols, colors
Regional compliance Legal requirements Ratings, gambling laws
Date/time formats Local conventions DD/MM/YYYY vs MM/DD/YYYY
Number formats Decimal separators 1,000.00 vs 1.000,00

Test Scenarios

Text Display

SCENARIO: Text Fits UI Elements
  GIVEN all localized strings
  WHEN displayed in target language
  THEN text fits within UI boundaries
  AND no truncation or overflow occurs
  AND text remains readable

SCENARIO: Dynamic Text Insertion
  GIVEN template "Player {name} scored {points} points"
  WHEN name="Alexander" and points=1000
  THEN German: "Spieler Alexander hat 1.000 Punkte erzielt"
  AND text fits UI element
  AND variables are correctly formatted for locale

SCENARIO: Plural Forms
  GIVEN English "1 coin" / "5 coins"
  WHEN displaying in Polish (4 plural forms)
  THEN correct plural form is used
  AND all plural forms are translated

Character Support

SCENARIO: CJK Character Rendering
  GIVEN Japanese localization
  WHEN displaying text with kanji/hiragana/katakana
  THEN all characters render correctly
  AND no missing glyphs (tofu boxes)
  AND line breaks respect CJK rules

SCENARIO: Special Characters
  GIVEN text with accented characters (é, ñ, ü)
  WHEN displayed in-game
  THEN all characters render correctly
  AND sorting works correctly

SCENARIO: User-Generated Content
  GIVEN player can name character
  WHEN name includes non-Latin characters
  THEN name displays correctly
  AND name saves/loads correctly
  AND name appears correctly to other players

Layout and Direction

SCENARIO: Right-to-Left Layout
  GIVEN Arabic localization
  WHEN viewing UI
  THEN text reads right-to-left
  AND UI elements mirror appropriately
  AND numbers remain left-to-right
  AND mixed content (Arabic + English) displays correctly

SCENARIO: Text Expansion Accommodation
  GIVEN English UI "OK" / "Cancel" buttons
  WHEN localized to German "OK" / "Abbrechen"
  THEN button expands or text size adjusts
  AND button remains clickable
  AND layout doesn't break

Locale-Specific Formatting

Date and Time

Locale Date Format Time Format
en-US 12/25/2024 3:30 PM
en-GB 25/12/2024 15:30
de-DE 25.12.2024 15:30 Uhr
ja-JP 2024年12月25日 15時30分

Numbers and Currency

Locale Number Currency
en-US 1,234.56 $1,234.56
de-DE 1.234,56 1.234,56 €
fr-FR 1 234,56 1 234,56 €
ja-JP 1,234.56 ¥1,235

Automated Test Examples

Unity

using UnityEngine.Localization;

[Test]
public void Localization_AllKeysHaveTranslations([Values("en", "de", "ja", "zh-CN")] string locale)
{
    var stringTable = LocalizationSettings.StringDatabase
        .GetTable("GameStrings", new Locale(locale));

    foreach (var entry in stringTable)
    {
        Assert.IsFalse(string.IsNullOrEmpty(entry.Value.LocalizedValue),
            $"Missing translation for '{entry.Key}' in {locale}");
    }
}

[Test]
public void TextFits_AllUIElements()
{
    var languages = new[] { "en", "de", "fr", "ja" };

    foreach (var lang in languages)
    {
        LocalizationSettings.SelectedLocale = new Locale(lang);

        foreach (var textElement in FindObjectsOfType<LocalizedText>())
        {
            var rectTransform = textElement.GetComponent<RectTransform>();
            var textComponent = textElement.GetComponent<Text>();

            Assert.LessOrEqual(
                textComponent.preferredWidth,
                rectTransform.rect.width,
                $"Text overflows in {lang}: {textElement.name}");
        }
    }
}

[TestCase("en", 1, "1 coin")]
[TestCase("en", 5, "5 coins")]
[TestCase("ru", 1, "1 монета")]
[TestCase("ru", 2, "2 монеты")]
[TestCase("ru", 5, "5 монет")]
public void Pluralization_ReturnsCorrectForm(string locale, int count, string expected)
{
    var result = Localization.GetPlural("coin", count, locale);
    Assert.AreEqual(expected, result);
}

Unreal

bool FLocalizationTest::RunTest(const FString& Parameters)
{
    TArray<FString> Cultures = {"en", "de", "ja", "ko"};

    for (const FString& Culture : Cultures)
    {
        FInternationalization::Get().SetCurrentCulture(Culture);

        // Test critical strings exist
        FText LocalizedText = NSLOCTEXT("Game", "StartButton", "Start");
        TestFalse(
            FString::Printf(TEXT("Missing StartButton in %s"), *Culture),
            LocalizedText.IsEmpty());

        // Test number formatting
        FText NumberText = FText::AsNumber(1234567);
        TestTrue(
            TEXT("Number should be formatted"),
            NumberText.ToString().Len() > 7); // Has separators
    }

    return true;
}

Godot

func test_all_translations_complete():
    var locales = ["en", "de", "ja", "es"]
    var keys = TranslationServer.get_all_keys()

    for locale in locales:
        TranslationServer.set_locale(locale)
        for key in keys:
            var translated = tr(key)
            assert_ne(translated, key,
                "Missing translation for '%s' in %s" % [key, locale])

func test_plural_forms():
    TranslationServer.set_locale("ru")

    assert_eq(tr_n("coin", "coins", 1), "1 монета")
    assert_eq(tr_n("coin", "coins", 2), "2 монеты")
    assert_eq(tr_n("coin", "coins", 5), "5 монет")
    assert_eq(tr_n("coin", "coins", 21), "21 монета")

func test_text_fits_buttons():
    var locales = ["en", "de", "fr"]

    for locale in locales:
        TranslationServer.set_locale(locale)
        await get_tree().process_frame  # Allow UI update

        for button in get_tree().get_nodes_in_group("localized_buttons"):
            var label = button.get_node("Label")
            assert_lt(label.size.x, button.size.x,
                "Button text overflows in %s: %s" % [locale, button.name])

Visual Verification Checklist

Text Display

  • No truncation in any language
  • Consistent font sizing
  • Proper line breaks
  • No overlapping text

UI Layout

  • Buttons accommodate longer text
  • Dialog boxes resize appropriately
  • Menu items align correctly
  • Scrollbars appear when needed

Cultural Elements

  • Icons are culturally appropriate
  • Colors don't have negative connotations
  • Gestures are region-appropriate
  • No unintended political references

Regional Compliance

Ratings Requirements

Region Rating Board Special Requirements
North America ESRB Content descriptors
Europe PEGI Age-appropriate icons
Japan CERO Strict content guidelines
Germany USK Violence restrictions
China GRAC Approval process

Common Regional Issues

Issue Regions Affected Solution
Blood color Japan, Germany Option for green/disable
Gambling imagery Many regions Remove or modify
Skulls/bones China Alternative designs
Nazi imagery Germany Remove entirely

Best Practices

DO

  • Test with native speakers
  • Plan for text expansion (reserve 30% extra space)
  • Use placeholder text during development (Lorem ipsum-style)
  • Support multiple input methods (IME for CJK)
  • Test all language combinations (UI language + audio language)
  • Validate string format parameters

DON'T

  • Hard-code strings in source code
  • Assume left-to-right layout
  • Concatenate translated strings
  • Use machine translation without review
  • Forget about date/time/number formatting
  • Ignore cultural context of images and icons