इंटरनेशनलाइज़ेशन (i18n)

Internationalization (i18n) वह engineering काम है जो product को कोड बदले बिना किसी भी भाषा और क्षेत्र के लायक बनाता है: text resource फ़ाइलों में रहता है, dates और amounts locale-aware formatting से आते हैं, layout कोई दिशा मानकर नहीं चलता, और हर layer Unicode store करती है। फिर localization (l10n) product को एक locale के लिए ढालती है, जैसे सऊदी अरब की अरबी (ar-SA) या भारत की हिंदी (hi-IN)।

एक ठोस मामला: checkout का कोड total को "Total: SAR " + amount की तरह बनाता है। English ठीक दिखती है। Arabic और Hindi में "Total" शब्द English ही रहता है, और label, code और amount का क्रम और number का format वैसा ही रहता है जैसा developer ने लिखा, locale के अपने currency pattern के अनुसार नहीं। कोई translator इसे ठीक नहीं कर सकता, क्योंकि यह text translation फ़ाइलों तक पहुँचा ही नहीं। यह i18n defect है, और यह lesson इसी class को जल्दी पकड़ने के बारे में है।

यह क्यों ज़रूरी है

ज़्यादातर i18n defects source भाषा में दिखते ही नहीं, इसलिए सिर्फ़ English में test करने वाली टीम उन्हें एक साथ हर दूसरे market में ship कर देती है। देर से मिलने पर इन्हें ठीक करना translation defects से महँगा भी पड़ता है: hard-coded string या fixed date pattern का मतलब है कोड बदलना, नया build और हर locale में retest, जबकि ग़लत translation resource फ़ाइल की एक line है।

Tester के लिए i18n की समझ तय करती है कि report कहाँ जाएगी। Arabic interface में सादा English label translator के लिए translation bug नहीं है; यह code defect है, और उसकी कोई string key है ही नहीं।

दो अलग काम: एक बार कोड में, फिर हर locale के लिए

Localization testing गाइड ने ये terms introduce किए; test design के लिए जो मायने रखता है वह है काम कहाँ होता है। Internationalization एक बार, कोड में, developers करते हैं: यह product का गुण है। Localization हर locale के लिए अलग से, content में, translators और local experts करते हैं: translated strings, local formats, क़ानूनी text, payment तरीक़े। कुछ टीमें दोनों को मिलाकर globalization (g11n) कहती हैं।

क्योंकि काम अलग जगहों पर होता है, defects भी अलग जगहों पर रहते हैं। i18n defect आम तौर पर source भाषा के अलावा हर locale में दिखता है, और सही data वाला कोई भी tester उसे reproduce कर सकता है। l10n defect एक locale में दिखता है और उसे परखने के लिए अक्सर native speaker चाहिए। एक ही screen पर दोनों हो सकते हैं: string template से बना price (i18n) और "cart" के लिए ग़लत Arabic शब्द (l10n)।

  • i18n सवाल: क्या product कोई भी locale ले सकता है? Translation आने से पहले test करें, pseudo-locale, Unicode data, right-to-left दिशा और non-default formats के साथ।
  • l10n सवाल: क्या यह locale सही है? Translation आने के बाद test करें, असली strings, असली formats और native speaker के साथ।
  • Locale, सिर्फ़ language नहीं: ar Arabic text चुनता है; ar-SA वह region जोड़ता है जो formats, currency और calendar defaults तय करता है। Language tags RFC 5646 के अनुसार होते हैं।
एक ही checkout screen पर string template से बना price i18n defect है जो translation से पहले कोड में मिलता है, जबकि "cart" के लिए ग़लत Arabic शब्द l10n defect है जो localized build में मिलता है।

Internationalization (i18n)

Product को किसी भी locale के लायक बनाना

कहाँ होता है, कौन करता है:
एक बार, कोड में, developers
Defect कहाँ रहता है:
Template, formatting code, layout rule या storage path
कौन देखता है:
आम तौर पर source भाषा के अलावा हर locale
Checkout screen पर:
"Total: SAR " + amount: "Total" English ही रहता है और amount locale format नहीं मानता
कब मिलता है:
Translation से पहले: pseudo-locale, Unicode data, right-to-left pseudo-locale
Report किसे जाती है:
Developers को, layer और string key (अगर है) के साथ

Localization (l10n)

Product को एक locale के लिए ढालना

कहाँ होता है, कौन करता है:
हर locale के लिए, content में, translators और local experts
Defect कहाँ रहता है:
एक locale की resource फ़ाइल या content
कौन देखता है:
सिर्फ़ उस एक locale के users
Checkout screen पर:
"cart" के लिए ग़लत Arabic शब्द, Arabic resource फ़ाइल में
कब मिलता है:
Translation के बाद: localized build, असली formats, native speaker
Report किसे जाती है:
Translator या localization lead को, key और screenshot के साथ

Externalised strings और locale data

String को externalise करने का मतलब है उसे कोड से निकालकर resource फ़ाइल में एक key के नीचे रखना: कोड checkout.total माँगता है और runtime मौजूदा locale का text लौटाता है। हर वाक्य named parameters वाला एक message होता है, जोड़े गए टुकड़े कभी नहीं, क्योंकि शब्दों का क्रम और agreement भाषाओं में अलग होते हैं। Counts plural categories इस्तेमाल करते हैं: Unicode CLDR के नियम English को दो, Hindi को दो और Arabic को छह देते हैं, इसलिए message में हर category का एक रूप होता है और formatter उसे चुनता है; नीचे की ICU MessageFormat syntax में # की जगह number आता है।

Locale data वह सब है जो runtime किसी locale के बारे में जानता है और जो translation नहीं है: date और number patterns, digits, currency symbols और उनकी जगह, calendar, हफ़्ते का पहला दिन, plural नियम और sort order। ज़्यादातर platforms पर यह CLDR से आता है और ECMAScript के Intl objects (ECMA-402) जैसे locale-aware APIs से कोड तक पहुँचता है। Internationalized कोड कभी DD/MM/YYYY जैसा pattern hard-code नहीं करता; वह user का locale tag API को देता है और जो लौटे उसे दिखाता है। CLDR data नए releases के साथ बदलता है, इसलिए test को expected format platform के अपने formatter से लेना चाहिए, किसी website से एक बार copy की गई value से नहीं।

  • Missing keys: हर locale फ़ाइल की source फ़ाइल से तुलना करें; जो key en.json में है और ar.json में नहीं, वह English पर fall back करती है या raw key दिखाती है।
  • Parameters: {name} और {amount} translation के बाद जस के तस रहने चाहिए; translated placeholder raw braces दिखाता है या formatter तोड़ देता है, और हटाया गया placeholder value को चुपचाप गायब कर देता है।
en.json
  "checkout.total":    "Total: {amount}"
  "checkout.nights":   "{count, plural, one {# night} other {# nights}}"
  "checkout.greeting": "Welcome back, {name}"

ar.json  (वही keys; Arabic में सभी छह plural categories)
  "checkout.total":    "الإجمالي: {amount}"
  "checkout.nights":   "{count, plural, zero {لا ليالي} one {ليلة واحدة} two {ليلتان}
                         few {# ليالٍ} many {# ليلة} other {# ليلة}}"
  "checkout.greeting": "أهلاً بعودتك يا {name}"

Tester क्या जाँचता है
  हर दिखने वाली string की key है       -> template में कुछ भी typed नहीं
  {amount} पहले से formatted आता है    -> locale API से, message से नहीं
  {count} हर plural category छूता है   -> Arabic के लिए 0, 1, 2, 3, 11 और 100

आज़माएँ: JSON डिफ़

Worked example: pseudo-locale में checkout screen

Pseudo-localization source strings से एक नक़ली locale बनाती है: अक्षरों पर accents लगते हैं, हर message लंबा होकर brackets में लिपट जाता है, और चाहें तो base direction right-to-left पलट जाती है। टीम screen अब भी पढ़ सकती है, और interface का जो text बदला हुआ नहीं दिखता वह कभी externalise हुआ ही नहीं। Translator की ज़रूरत नहीं, इसलिए यह CI में हर build पर चल सकती है। उदाहरण के लिए Android en-XA (accents वाला, लंबा text) और ar-XB (right-to-left) pseudo-locales देता है।

नीचे एक hotel checkout screen English और pseudo-locale में है, साथ में हर line tester को क्या बताती है। सादी English खोजें, एक वाक्य की जगह कई bracket जोड़े खोजें, गायब closing bracket खोजें, और accented अक्षरों की जगह question marks खोजें।

  • Expansion: हर string टीम के चुने factor से लंबी होती है, क्योंकि कई translations English से लंबी होती हैं और छोटे labels सबसे ज़्यादा बढ़ते हैं। जो layout इसे झेल ले वह आम तौर पर असली Arabic और Hindi strings भी झेल लेता है।
  • Right-to-left pseudo-locale: यह Arabic translation के बिना base direction पलटती है, इसलिए बिना-mirror icons, ग़लत जगह के back arrows और ग़लत तरफ़ aligned text Arabic फ़ाइल बनने से हफ़्तों पहले दिख जाते हैं।
English                   Pseudo-locale                  Tester क्या देखता है
------------------------  -----------------------------  --------------------------------
Checkout                  [Çĥéçķöüţ ····]                ठीक: externalised
Book now                  Book now                       template में hard-coded
You have 2 guests         [Ýöü ĥàṽé] 2 [ĝüéšţš]          तीन टुकड़े: concatenated
Total: SAR 1,250.00       Total: SAR 1,250.00            hard-coded: कभी key थी ही नहीं
Room type                 [?ööm ?ý?é ····]               question marks: non-UTF-8 रास्ता
Cancel booking            [Çàñçéļ ḃööķí                  truncated: fixed-width button
Welcome back, Ahmed       [Ŵéļçömé ḃàçķ, Ahmed ····]     ठीक: {name} बचा रहा

आज़माएँ: बहुभाषी टेस्ट डेटा जनरेटर

आम i18n defects और वे कहाँ रहते हैं

ज़्यादातर i18n defects कुछ ही classes में आते हैं। हर class का एक symptom है, कोड में एक जगह और उसे पकड़ने का एक सस्ता तरीक़ा; class पहचान लें तो आप सिर्फ़ symptom नहीं, कारण report कर पाते हैं।

  • Validation messages, API errors, emails, labels और image text में hard-coded strings। पकड़ने का तरीक़ा: pseudo-locale, फिर Arabic, हर message पढ़ते हुए, उन्हें भी जो error होने पर ही दिखते हैं।
  • Concatenation और if वाले plurals: "You have " + n + " items", count === 1 ? "night" : "nights"। Symptom: bracket वाले टुकड़े, "ليلتان" की जगह "2 ليلة"। पकड़ने का तरीक़ा: counts 0, 1, 2, 3, 11 और 100।
  • Fixed formats: DD/MM/YYYY templates, हाथ से रखे currency codes, कोड में लिखा decimal point। Symptom: हर locale में एक ही format। पकड़ने का तरीक़ा: ar-SA और hi-IN, platform के अपने formatter से तुलना करके।
  • Layout में physical direction: text की दिशा के साथ चलने वाली logical properties (margin-inline-start, text-align: start) और dir attribute की जगह margin-left और text-align: left। Symptom: Arabic page जिसका layout English ही रहता है। पकड़ने का तरीक़ा: right-to-left pseudo-locale।
  • Non-Unicode रास्ते: कोई column, API या export जो Unicode की जगह कोई पुराना (legacy) encoding इस्तेमाल करे, या bytes में गिनी गई length limit। Symptom: question marks, mojibake, 100-character field जो 60 Arabic अक्षर (UTF-8 में 120 bytes) reject कर दे। पकड़ने का तरीक़ा: हर field में Unicode datasets, फिर stored value जाँचें।
  • रास्ते में खोया locale: interface Arabic है पर email, PDF receipt या SMS English। पकड़ने का तरीक़ा: Arabic में एक flow पूरा करें और हर वह output खोलें जो screen नहीं है।

आज़माएँ: Unicode डेटासेट जनरेटर आज़माएँ: स्ट्रिंग लेंथ काउंटर आज़माएँ: अरबी टेस्ट डेटा जनरेटर आज़माएँ: हिंदी टेस्ट डेटा जनरेटर

आम गलतियाँ

  • कुछ भी test करने से पहले translation का इंतज़ार करना; i18n defects pseudo-locale में हफ़्तों पहले दिख जाते हैं।
  • Hard-coded English label को translation request की तरह file करना; translator ऐसा text ठीक नहीं कर सकता जिसकी key ही नहीं।
  • सिर्फ़ pages test करना: emails, PDFs, SMS, API errors और exports ही वे जगहें हैं जहाँ locale आम तौर पर खो जाता है।
  • English pass को सबूत मानना; ज़्यादातर i18n defects source भाषा में कभी नहीं दिखते।
  • Forms में सिर्फ़ Latin test data इस्तेमाल करना, जिससे non-Unicode रास्ता कभी exercise नहीं होता।
  • Pseudo-locale को असली Arabic और Hindi builds और linguistic review का विकल्प मान लेना।

QA का नज़रिया

Practice में i18n testing requirements review से तीन सवालों के साथ शुरू होती है: कौन-से locales ship होने हैं, locale कहाँ से आता है (user setting, Accept-Language, device, URL), और क्या जान-बूझकर translate नहीं किया जाता (brand names, codes, क़ानूनी text)। Code review में, या developer के साथ, पूछें कि strings externalised हैं या नहीं, formatting locale API से गुज़रती है या नहीं, और layout logical properties इस्तेमाल करता है या नहीं।

Execution में पहले pseudo-locale build चलाएँ, फिर Unicode test data के साथ Arabic और Hindi builds, फिर हर वह output जो screen नहीं है। Report में locale tag, string key (अगर है), screen या output, screenshot और वह layer दर्ज करें जहाँ value ग़लत हुई: template, resource फ़ाइल, API, database या email service। "Checkout template में hard-coded, हर locale में reproduce होता है" एक जगह ठीक होता है; "Arabic translation missing" ऐसे translator के पास जा सकता है जो कुछ नहीं कर सकता।

अभ्यास

Pseudo-locale run के findings classify करें

आपका काम

एक hotel booking app को pseudo-locale (en-XA) में और फिर Arabic (ar-SA) में चलाया गया। नीचे की आठ findings में से हर एक के लिए तय करें कि वह i18n defect है या l10n defect, बताएँ कि वह कहाँ रहता है (code, resource फ़ाइल या locale content) और report किसे मिलनी चाहिए।

फिर finding 3 के लिए एक line का bug title लिखें जो सिर्फ़ symptom नहीं, कारण बताए।

सामग्री
1  Pseudo-locale में "Book now" सादा Book now दिखता है; बाक़ी हर button
   [Ḃööķ ñöẃ ····] जैसा text दिखाता है।
2  Guest line [Ýöü ĥàṽé] 2 [ĝüéšţš] पढ़ी जाती है: तीन bracket वाले टुकड़े।
3  Arabic में total line "Total: SAR 1,250.00" है, यानी English text और Western
   digits, जबकि page की बाक़ी हर amount में Arabic-Indic digits और ر.س. हैं।
4  Room type "Deluxe" search page पर "ديلوكس" और invoice पर "فاخرة" है।
5  Check-in date field हर locale में सिर्फ़ MM/DD/YYYY स्वीकार करता है।
6  Arabic booking के बाद confirmation email English में आता है, जबकि Arabic
   email template पूरा है।
7  Arabic में दो रातें "ليلتان" की जगह "2 ليلة" दिखती हैं; English सही है। Arabic
   फ़ाइल में इस text की वही दो entries हैं जो English में हैं, एक 1 के लिए और एक
   बाक़ी हर count के लिए, और कोड सिर्फ़ इन्हीं दो को पढ़ता है।
8  Arabic cancellation policy check-in से 24 घंटे पहले तक free cancellation देती है;
   English source text 48 घंटे कहता है।
चरण
  1. पूछें कि finding हर locale में दिखती है या सिर्फ़ Arabic में।
  2. पूछें कि क्या resource फ़ाइल वाला translator इसे ठीक कर सकता है।
  3. Layer का नाम लें: template, formatting code, resource फ़ाइल, email service या locale content।
  4. Finding 3 का title symptom, जगह और कारण के रूप में लिखें।
मॉडल उत्तर दिखाएँ
मॉडल उत्तर

i18n, कोड में, developers को: 1 template में hard-coded string; 2 concatenated वाक्य; 3 hard-coded label और locale API की जगह string template से बना amount; 5 locale-aware date input की जगह fixed date pattern; 6 email service को locale नहीं दिया गया; 7 count === 1 जैसी दो-तरफ़ा जाँच से चुना plural, जबकि Arabic को छह categories चाहिए। हर एक कोड में एक बार, सभी locales के लिए, ठीक होता है।

l10n, Arabic content में, string keys और screenshots के साथ translator या localization lead को: 4 दो screens के बीच असंगत terminology, Arabic resource फ़ाइल में; 8 ग़लत translation जो cancellation policy का अर्थ बदल देता है, localized policy text में।

Finding 7 सिर्फ़ Arabic में दिखती है, इसलिए step 1 l10n की ओर इशारा करता है, लेकिन step 2 फ़ैसला करता है: कोई translator ऐसी फ़ाइल में "ليلتان" नहीं लिख सकता जो 1 के लिए एक रूप और बाक़ी सबके लिए एक रूप देती है। Fix है CLDR categories वाला plural message, कोड में।

Finding 3 का title: "ar-SA में checkout total English में Western digits के साथ Total: SAR 1,250.00 दिखाता है: label hard-coded है और amount locale API की जगह string template से formatted है"।

अक्सर पूछे जाने वाले सवाल

Internationalization developers का काम है या testers का?

इसे बनाना engineering का काम है; इसे जाँचना test का काम। Testers i18n defects सबसे पहले requirements में locale decisions review करके, हर build पर pseudo-locale चलाकर और हर layer से Unicode data गुज़ारकर पाते हैं, और हर defect को उसके कारण के साथ report करते हैं ताकि वह कोड में एक बार ठीक हो, हर locale में patch न करना पड़े।

क्या pseudo-localization असली Arabic और Hindi में testing की जगह ले सकती है?

नहीं। यह वे defects पकड़ती है जो असली translation पर निर्भर नहीं: hard-coded strings, concatenation, truncation, encoding और direction की समस्याएँ। Terminology, grammar, cultural fit और असली locale formats के लिए अब भी localized builds, localized test data और वह native-speaker review चाहिए जो translation और linguistic testing वाले lesson में आती है।

Language और locale में क्या फ़र्क़ है?

ar जैसा language subtag चुनता है कि कौन-सा translation दिखे। Locale उसमें region जोड़ता है, जैसे ar-SA या ar-EG (RFC 5646 के अनुसार दोनों language tags हैं), और वह region formats, currency, calendar और दूसरे defaults तय करता है। एक ही language और अलग regions वाले दो users एक ही कोड से अलग dates और amounts देख सकते हैं।

क्या i18n defects खोजने के लिए मुझे Arabic या Hindi आनी चाहिए?

नहीं। i18n defects सादी English, bracket के टुकड़ों, ग़लत digits, टूटी layout direction या खोए characters के रूप में दिखते हैं, और कोई भी tester उन्हें pseudo-localization और generated test data से देख सकता है। Translation की quality परखने के लिए ज़रूर native speaker चाहिए।

संदर्भ

  • Internationalization (i18n) ActivityW3Cबहुभाषी वेब कंटेंट बनाने और टेस्ट करने के लिए W3C के internationalization लेख, ट्यूटोरियल और जाँचें।
  • RFC 5646: Tags for Identifying LanguagesIETF · 2009BCP 47 भाषा टैग (ar, ar-SA, hi-IN, en-GB) — lang एट्रिब्यूट, Accept-Language और locale सेटिंग में इस्तेमाल होने वाले पहचानकर्ता।
  • Unicode CLDR ProjectUnicode ConsortiumCommon Locale Data Repository: तारीख़, समय, संख्या व मुद्रा फ़ॉर्मेट और plural नियमों का locale डेटा जिसे ज़्यादातर प्लेटफ़ॉर्म इस्तेमाल करते हैं।
  • ECMAScript Internationalization API Specification (ECMA-402)Ecma International (TC39)JavaScript Intl API का स्पेसिफ़िकेशन — ब्राउज़र में तारीख़, संख्या, मुद्रा, सूची और plural नियमों की locale-aware फ़ॉर्मेटिंग।

Mutqan tools से अभ्यास करें

i18n और RTL/LTR मिश्रण जाँचने के लिए एक ही रिकॉर्ड कई भाषाओं (अंग्रेज़ी, अरबी, हिंदी और अन्य) में जनरेट करें।

टेस्ट डेटा

कई लिपियों (अरबी, देवनागरी, CJK, सिरिलिक), emoji, संयोजक चिह्न और normalisation रूपों में Unicode टेस्ट स्ट्रिंग जनरेट करें।

टेस्ट डेटा

दो JSON डॉक्यूमेंट की सिमैंटिक तुलना करें और जोड़ी गई, हटाई गई तथा बदली गई वैल्यू हाइलाइट करें।

JSON और डेटा

लोकलाइज़ेशन टेस्टिंग के लिए अरबी नाम, पते, वाक्य, संख्याएँ (अरबी-हिंदसी अंक) और RTL edge case जनरेट करें।

टेस्ट डेटा

और गहराई से

इस topic में आपकी प्रगति

QA रोडमैप का हिस्सा