लोकलाइज़ेशन टेस्टिंग
लोकलाइज़ेशन टेस्टिंग यह जाँचती है कि कोई प्रोडक्ट किसी ख़ास locale — यानी भाषा और क्षेत्र का जोड़, जैसे सऊदी अरब में अरबी (ar-SA) या भारत में हिंदी (hi-IN) — के यूज़र्स के लिए ठीक काम करता है, सही पढ़ा जाता है और सही दिखता है। इसमें अनुवादित टेक्स्ट आता है, लेकिन इसके ज़्यादातर डिफ़ेक्ट अनुवाद की गलतियाँ नहीं होते: वे होते हैं ग़लत कैलेंडर में तारीख़ें, ग़लत separator वाली रकम, बीच से कटे वाक्य, टेक्स्ट की लंबाई या दिशा बदलते ही टूटते लेआउट, और ऐसे अक्षर जो फ़ॉर्म और डेटाबेस के बीच कहीं प्रश्नचिह्न बन जाते हैं।
यह गाइड इस क्षेत्र का प्रवेश-द्वार है। यह internationalization, localization और globalization को अलग करती है, उन क्षेत्रों का नक्शा देती है जिन्हें टेस्टर को कवर करना है, और अरबी, हिंदी और अंग्रेज़ी — वही तीन भाषाएँ जिनमें Mutqan Tools ख़ुद चलता है — के लिए ठोस जाँचें, डेटा और डिफ़ेक्ट उदाहरण देती है। Right-to-left लेआउट और bidirectional टेक्स्ट की अपनी अलग गाइड है, अरबी इंटरफ़ेस की RTL टेस्टिंग; यह पेज उनका सार देता है और बाक़ी सब पर गहराई में जाता है।
i18n, l10n और g11n: असल में क्या टेस्ट होता है
Internationalization (i18n) एक इंजीनियरिंग गुण है: प्रोडक्ट ऐसे बनाया जाता है कि कोड बदले बिना उसे किसी भी locale के लिए ढाला जा सके। टेक्स्ट टेम्पलेट में नहीं, resource फ़ाइलों में रहता है; तारीख़, संख्या और मुद्रा locale-aware फ़ॉर्मेटिंग API से गुज़रती हैं; टेक्स्ट की दिशा मानकर नहीं चली जाती; स्टोरेज और ट्रांसपोर्ट शुरू से अंत तक Unicode हैं। Localization (l10n) एक locale के लिए अनुकूलन है: अनुवादित strings, locale फ़ॉर्मेट, स्थानीय कंटेंट, क़ानूनी टेक्स्ट, पेमेंट तरीक़े, पते और फ़ोन के फ़ॉर्मेट। Globalization (g11n) उस बिज़नेस और इंजीनियरिंग प्रयास का व्यापक नाम है जो दोनों को जोड़कर एक प्रोडक्ट को कई बाज़ारों में उपलब्ध कराता है।
यह फ़र्क़ इसलिए मायने रखता है क्योंकि डिफ़ेक्ट अलग होते हैं। i18n डिफ़ेक्ट कोड में रहता है और हर locale में दिखता है — hard-coded मुद्रा चिह्न, जोड़-जोड़कर बना वाक्य, तय pattern से parse की गई तारीख़। l10n डिफ़ेक्ट एक locale के कंटेंट में रहता है — ग़लत शब्द, छूटा अनुवाद, ग़लत पता फ़ॉर्मेट। i18n डिफ़ेक्ट सबसे सस्ते तब मिलते हैं जब अभी कोई अनुवाद है ही नहीं, pseudo-localization से; l10n डिफ़ेक्ट के लिए असली अनुवाद चाहिए, और भाषा की गुणवत्ता के लिए मातृभाषी व्यक्ति।
- Locale — BCP 47 language tag (RFC 5646) से पहचाना जाता है: ar, ar-SA, hi-IN, en-IN। भाषा वाला हिस्सा अनुवाद चुनता है; क्षेत्र वाला हिस्सा फ़ॉर्मेट, मुद्रा और डिफ़ॉल्ट कैलेंडर चुनता है।
- Internationalization टेस्टिंग — क्या प्रोडक्ट locales को सपोर्ट कर भी सकता है? उसे pseudo-localized टेक्स्ट, Unicode डेटा, right-to-left दिशा और ग़ैर-डिफ़ॉल्ट फ़ॉर्मेट के साथ चलाएँ।
- Localization टेस्टिंग — क्या यह ख़ास locale सही है? संदर्भ में अनुवाद, फ़ॉर्मेट, सांस्कृतिक उपयुक्तता, असली strings के साथ लेआउट।
लोकलाइज़ेशन टेस्टिंग का नक्शा
लोकलाइज़ेशन टेस्टिंग ऐसे क्षेत्रों में फैली है जिनके लिए अलग कौशल और अलग डेटा चाहिए। हर locale की कवरेज प्लान करने के लिए यह नक्शा इस्तेमाल करें; आगे के सेक्शन हर क्षेत्र से गुज़रते हैं, और right-to-left लेआउट RTL टेस्टिंग गाइड में विस्तार से है।
- भाषा और अनुवाद गुणवत्ता — शब्दावली, संदर्भ, पूर्णता, plural और लिंग रूप, message parameters, truncation।
- Locale फ़ॉर्मेट — तारीख़ और कैलेंडर (ग्रेगोरियन और हिजरी), समय और time zone, संख्याएँ और अंक, मुद्रा, इकाइयाँ, पते, फ़ोन नंबर और व्यक्तिगत नाम।
- टेक्स्ट और लिपि हैंडलिंग — encoding, Unicode normalization, grapheme cluster, फ़ॉन्ट, sorting, search और input methods।
- लेआउट — टेक्स्ट का फैलना और सिकुड़ना, लाइन के ऊपर-नीचे चिह्नों वाली लिपियों के लिए line height, और अरबी के लिए पूरा right-to-left mirroring और bidirectional-text क्षेत्र।
- Locale चयन और fallback — प्रोडक्ट locale कैसे चुनता है (यूज़र सेटिंग, Accept-Language हेडर, डिवाइस, URL), असमर्थित locale पर क्या होता है, और क्या चुनाव ईमेल, PDF, SMS और push notification तक पहुँचता है।
- हर locale में एक्सेसिबिलिटी — lang एट्रिब्यूट जो screen reader को बताता है कि कौन-सी आवाज़ और उच्चारण नियम इस्तेमाल करने हैं, और आइकन व कंट्रोल के अनुवादित accessible names।
भाषा और अनुवाद की गुणवत्ता
अनुवादक आमतौर पर स्क्रीन देखे बिना स्प्रेडशीट या translation-management सिस्टम से काम करते हैं, और कई अनुवाद डिफ़ेक्ट यहीं से आते हैं। अंग्रेज़ी का "Save" क्रिया (फ़ाइल सेव करें) भी हो सकता है और संज्ञा (डिस्काउंट में बचत) भी; "Open" स्टेटस भी हो सकता है और कमांड भी; बिना संदर्भ के अनुवादक एक चुन लेता है। टेस्टर का काम है हर string को असली स्क्रीन पर देखना और स्क्रीनशॉट के साथ string key रिपोर्ट करना, ताकि सुधार सही resource में पहुँचे।
Plural सबसे आम संरचनात्मक डिफ़ेक्ट है। अंग्रेज़ी में दो cardinal plural रूप हैं। Unicode CLDR के plural नियम अरबी को छह श्रेणियाँ देते हैं — zero (0), one (1), two (2), few (जिन संख्याओं के आख़िरी दो अंक 3–10 हों, जैसे 3 या 103), many (आख़िरी दो अंक 11–99) और other (जैसे 100–102) — और हिंदी को दो, जिसमें "one" रूप 0 और 1 दोनों के लिए है। जो कोड count === 1 से रूप चुनता है वह अरबी के लिए बनावट से ही ग़लत है। सुधार है plural श्रेणियों वाला message format; टेस्ट है संख्याओं की ऐसी तालिका जो हर श्रेणी को छुए।
- शब्दावली की एकरूपता — स्क्रीन, हेल्प पेज और ईमेल में हर अवधारणा के लिए एक ही शब्द, glossary से मिलान करके। एक स्क्रीन पर कार्ट को "सला" (سلة) और दूसरी पर "अरबा" (عربة) कहना डिफ़ेक्ट है।
- अनअनुवादित strings — अरबी या हिंदी इंटरफ़ेस के भीतर छूटी अंग्रेज़ी; validation मैसेज, API एरर, ईमेल और स्प्रिंट के आख़िर में जोड़ी गई strings में आम।
- Concatenated strings — टुकड़ों से बने वाक्य ("You have" + n + "items") सही अनुवादित नहीं हो सकते क्योंकि शब्द-क्रम और अन्वय अलग होते हैं; हर वाक्य parameters वाला एक message होना चाहिए।
- Message parameters — अनुवाद के भीतर {name} या %s बिना बदले बचे रहने चाहिए; अनुवादित या हटाया गया parameter कच्चे braces दिखाता है या formatter को क्रैश कर देता है।
- लिंग और संबोधन — अरबी क्रियाएँ और विशेषण लिंग से मेल खाते हैं; तय करें कि मैसेज यूज़र को कैसे संबोधित करें और जाँचें कि फ़ैसला एकरूप लागू है। हिंदी में आप/तुम का चुनाव भी इसी तरह तय करें।
# ICU MessageFormat, Arabic: one message, six CLDR plural categories
cart.items = {count, plural,
zero {السلة فارغة}
one {منتج واحد في السلة}
two {منتجان في السلة}
few {# منتجات في السلة}
many {# منتجًا في السلة}
other {# منتج في السلة}
}
# Counts that hit every Arabic category
0 (zero) · 1 (one) · 2 (two) · 3, 10, 103 (few) · 11, 99 (many) · 100, 101, 102 (other)
# Hindi has two categories: one (0 and 1) and other
0, 1 (one) · 2, 5, 1.5 (other)count === 1 जाँच सिर्फ़ 1 और 100–102 पर सही है।अरबी (ar): CLDR श्रेणी
- 0
zero - 1
one - 2
two - 3–10
few - 11–99
many - 100–102
other - 103–110
few
count === 1 जाँच: one रूप, वरना other
- 0ग़लत, चाहिए zeroफ़ेल
- 1सहीपास
- 2–99ग़लत, चाहिए two, few या manyफ़ेल
- 100–102सहीपास
- 103–110ग़लत, चाहिए fewफ़ेल
हिंदी (hi): CLDR श्रेणी
- 0, 1
one - 1.5, 2, 5 …
other
पैमाने के अनुपात में नहीं: सैंपल की हर टेस्ट संख्या को, और 110 को (जहाँ few ख़त्म होती है), अपनी जगह मिली है। जाँच को अंग्रेज़ी-शैली के कोड की तरह पढ़ा गया है: 1 के लिए one रूप, बाक़ी हर संख्या के लिए other रूप। हिंदी में यह 0 पर ग़लत है।
Pseudo-localization: अनुवाद से पहले i18n डिफ़ेक्ट खोजें
Pseudo-localization हर UI string को अपने-आप बदले गए ऐसे रूप से बदल देता है जिसे टीम अब भी पढ़ सके: accent वाले अक्षर, अतिरिक्त लंबाई, और हर message की शुरुआत और अंत बताने वाले ब्रैकेट। प्रोडक्ट को pseudo-locale में चलाएँ और हर वह डिफ़ेक्ट श्रेणी तुरंत दिख जाती है जिसके लिए असली अनुवाद ज़रूरी नहीं — hard-coded टेक्स्ट सादी अंग्रेज़ी रहता है, जोड़कर बना वाक्य कई ब्रैकेट वाले टुकड़ों में दिखता है, truncation आख़िरी ब्रैकेट काट देता है, और ASCII के बाहर के अक्षर encoding समस्याएँ उजागर करते हैं।
Android दो pseudo-locale देता है जिन्हें debug बिल्ड में चालू किया जा सकता है: English (XA), जो accent जोड़ता है, टेक्स्ट लंबा करता है और हर message को ब्रैकेट में रखता है; और AR (XB), जो दिशा right-to-left कर देता है और अक्षरों का क्रम उलट देता है, ताकि टीम कोई RTL भाषा जाने बिना mirroring और bidirectional समस्याएँ पकड़ सके। वेब पर pseudo-locale आमतौर पर एक और resource फ़ाइल होती है जो बिल्ड के दौरान source strings से जनरेट होती है।
Source (en): Save changes
Pseudo (expanded): [Ŝàṽé çĥàñĝéš ·····]
RTL pseudo: same text, base direction switched to right-to-left
What each symptom on screen means:
Save changes -> hard-coded string, never externalised
[Ŝàṽé] [çĥàñĝéš] -> sentence assembled by concatenation
[Ŝàṽé çĥàñĝ -> truncated: no room for longer translations
[Ŝ?ṽ? ?ĥ?ñĝ?š] -> characters lost in an encoding conversionतारीख़, कैलेंडर और time zone
तारीख़ का फ़ॉर्मेट सिर्फ़ दिन और महीने का क्रम नहीं है। Locale तय करता है कैलेंडर, महीनों के नाम, अंक, separator, हफ़्ते का पहला दिन और 12 या 24 घंटे की घड़ी। सऊदी अरब में दो कैलेंडर रोज़ इस्तेमाल होते हैं: ग्रेगोरियन कैलेंडर और हिजरी कैलेंडर, जिसे सऊदी अरब Umm al-Qura (उम्म अल-क़ुरा) कैलेंडर के रूप में मानकीकृत करता है। कई प्रोडक्ट दोनों दिखाते हैं या यूज़र को चुनने देते हैं; जो भी जगह तारीख़ दिखाती, लेती, स्टोर करती या तुलना करती है, उसे साफ़ होना चाहिए कि वह कौन-सा कैलेंडर इस्तेमाल करती है।
यह मानकर न चलें कि "ar-SA" क्या देगा। Locale के डिफ़ॉल्ट runtime के भीतर के CLDR डेटा से आते हैं और वर्ज़न के साथ बदलते हैं: पुराने runtime ar-SA तारीख़ें डिफ़ॉल्ट रूप से हिजरी कैलेंडर में दिखाते थे, जबकि नए runtime अरबी-इंडिक अंकों के साथ ग्रेगोरियन कैलेंडर इस्तेमाल करते हैं। कैलेंडर और numbering system स्पष्ट रूप से माँगें — जैसे Unicode locale extensions ar-SA-u-ca-islamic-umalqura या ar-SA-u-nu-latn से — और नतीजा हर उस runtime पर टेस्ट करें जिसे आप शिप करते हैं: सर्वर, ब्राउज़र और मोबाइल। अलग-अलग हिजरी गणनाएँ (Umm al-Qura, tabular civil) एक ही दिन को अलग तारीख़ पर रख सकती हैं, इसलिए conversion टेस्ट में कैलेंडर का नाम होना चाहिए, सिर्फ़ "हिजरी" नहीं।
Time zone IANA tz डेटाबेस से आते हैं। Asia/Riyadh UTC+03:00 है और सऊदी अरब daylight saving time नहीं मानता; Asia/Kolkata UTC+05:30 है, वह भी बिना daylight saving के। इससे DST डिफ़ेक्ट लोकल टेस्टिंग में अदृश्य रहते हैं पर यूरोप या उत्तरी अमेरिका के यूज़र्स के लिए असली होते हैं। Instants को UTC में या स्पष्ट offset (ISO 8601) के साथ स्टोर करें, यूज़र के zone में सिर्फ़ डिस्प्ले के लिए बदलें, और आधे घंटे का offset, DST मानने वाला zone, और आधी रात के पास के समय टेस्ट करें, जहाँ कैलेंडर का दिन बदल जाता है।
- हर तारीख़ फ़ील्ड अपना कैलेंडर बताए; हिजरी date picker में तारीख़ चुनने पर वही वैल्यू स्टोर हो जो समकक्ष ग्रेगोरियन तारीख़ चुनने पर होती।
- महीने और साल का अंत: Umm al-Qura के महीने 29 या 30 दिन के होते हैं; दोनों कैलेंडर में महीने और साल का आख़िरी दिन टेस्ट करें।
- आधी रात का खिसकाव: रियाद समय 01:30 पर दिया गया ऑर्डर UTC में पिछले दिन पड़ता है; UTC दिन के हिसाब से समूह बनाने वाली रिपोर्ट उसे ग़लत तारीख़ पर दिखाती है।
- हफ़्ता और वीकेंड: हफ़्ते का पहला दिन locale के अनुसार बदलता है, और सऊदी अरब में वीकेंड शुक्रवार और शनिवार है; कैलेंडर, शेड्यूल और business-day गणना प्रोडक्ट के नियम पर चलें, hard-coded नियम पर नहीं।
One instant: 2026-09-28T09:05:00Z
(example output from Node.js 22 with ICU 78 / CLDR 48; other runtimes may differ)
ar-SA ٢٨ سبتمبر ٢٠٢٦
ar-SA-u-nu-latn 28 سبتمبر 2026
ar-SA-u-ca-islamic-umalqura ١٧ ربيع الآخر ١٤٤٨ هـ
hi-IN 28 सितंबर 2026
en-US September 28, 2026
Time in Asia/Riyadh (UTC+03:00) 12:05
Time in Asia/Kolkata (UTC+05:30) 14:35आज़माएँ: तारीख़ टेस्ट डेटा जनरेटर आज़माएँ: Timezone कन्वर्टर आज़माएँ: टाइमस्टैम्प कन्वर्टर आज़माएँ: ISO 8601 कन्वर्टर
संख्याएँ, अंक और मुद्रा
अरबी टेक्स्ट पश्चिमी अंक (0–9) या अरबी-इंडिक अंक (٠١٢٣٤٥٦٧٨٩) इस्तेमाल कर सकता है, और अरबी-इंडिक अंकों के साथ separator भी बदलते हैं: अरबी दशमलव separator ٫ (U+066B) और अरबी हज़ार separator ٬ (U+066C)। हिंदी टेक्स्ट आमतौर पर पश्चिमी अंक इस्तेमाल करता है, हालाँकि देवनागरी अंक (०–९) मौजूद हैं और माँगे जा सकते हैं। भारत बड़ी संख्याओं को अलग तरह समूहित करता है — 12,34,567, यानी लाख (1,00,000) और करोड़ (1,00,00,000) प्रणाली — en-IN और hi-IN दोनों में। हर locale के लिए तय करें कि प्रोडक्ट कौन-से अंक और कौन-सा grouping इस्तेमाल करेगा, फिर डिस्प्ले और इनपुट दोनों टेस्ट करें: यूज़र रकम या फ़ोन फ़ील्ड में अरबी-इंडिक अंक टाइप कर सकता है, और प्रोडक्ट को या तो उन्हें स्वीकार करके normalise करना चाहिए या साफ़ मैसेज के साथ अस्वीकार।
मुद्राएँ ISO 4217 कोड से पहचानी जाती हैं — सऊदी रियाल के लिए SAR और भारतीय रुपये के लिए INR, दोनों की दो minor units। रकम को locale से फ़ॉर्मेट करें, string टेम्पलेट से नहीं: चिह्न, उसकी जगह और spacing locale के अनुसार बदलते हैं। सऊदी सेंट्रल बैंक ने 2025 में रियाल का अलग चिह्न पेश किया, और Unicode 17.0 उसे U+20C1 SAUDI RIYAL SIGN के रूप में encode करता है; अगर आपका डिज़ाइन इसे इस्तेमाल करता है तो जाँचें कि आपके लक्षित डिवाइस के कौन-से फ़ॉन्ट इसे दिखा सकते हैं, क्योंकि जिस फ़ॉन्ट में glyph नहीं है वह ख़ाली बॉक्स दिखाता है।
Locale से फ़ॉर्मेट की गई strings में अदृश्य अक्षर होते हैं। ar-SA के लिए SAR रकम फ़ॉर्मेट करने पर दोनों सिरों पर right-to-left mark (U+200F) और मुद्रा से पहले no-break space आता है, इसलिए हाथ से टाइप की गई string से तुलना करने वाला टेस्ट फ़ेल होता है जबकि स्क्रीन सही दिखती है। उसी फ़ॉर्मेटिंग API के आउटपुट से तुलना करें, या assertion में अदृश्य अक्षरों को जान-बूझकर हटाएँ।
- Parsing: "1.234" कुछ locales में एक हज़ार दो सौ चौंतीस है और कुछ में एक दशमलव दो तीन चार; डिस्प्ले के लिए फ़ॉर्मेट की गई वैल्यू को उसी locale से parse करना चाहिए।
- फ़ोन नंबर, IBAN और ID नंबर पहचानकर्ता हैं, मात्राएँ नहीं: डिस्प्ले में उन्हें न group करें, न उनके अंक बदलें।
1234567.5 as currency, per locale
(example output from Node.js 22 with ICU 78 / CLDR 48)
ar-SA SAR ١٬٢٣٤٬٥٦٧٫٥٠ ر.س.
(U+200F at start and end, U+00A0 before ر.س.)
ar-SA-u-nu-latn SAR 1,234,567.50 ر.س.
hi-IN INR ₹12,34,567.50
en-IN INR ₹12,34,567.50
en-US SAR SAR 1,234,567.50
1234567 with Devanagari digits (hi-IN-u-nu-deva): १२,३४,५६७आज़माएँ: अरबी टेस्ट डेटा जनरेटर आज़माएँ: हिंदी टेस्ट डेटा जनरेटर आज़माएँ: डेसिमल डेटासेट जनरेटर
टेक्स्ट, Unicode और लिपियाँ
हर लेयर को UTF-8 पर सहमत होना चाहिए: HTML meta charset और HTTP Content-Type, फ़ॉर्म सबमिशन, API, message queue, डेटाबेस कॉलम और कनेक्शन, लॉग, और CSV या PDF export। जब कोई लेयर UTF-8 bytes को किसी पुराने single-byte encoding में पढ़ती है तो नतीजा mojibake होता है — "مرحبا" कुछ ऐसा बन जाता है "Ù…Ø±ØØ¨Ø§" — और एक round trip नुक़सान को स्थायी बना सकता है। अक्षरों की जगह प्रश्नचिह्न का मतलब आमतौर पर है कि किसी conversion में अक्षर खो गए; ख़ाली बॉक्स का मतलब आमतौर पर है कि फ़ॉन्ट में glyph नहीं है। MySQL में पुराना utf8 (utf8mb3) character set अरबी और देवनागरी तो स्टोर करता है पर supplementary (चार-byte) अक्षर नहीं, जिनमें ज़्यादातर emoji आते हैं; utf8mb4 पूरा Unicode स्टोर करता है।
एक ही दिखने वाला टेक्स्ट अलग-अलग code point क्रमों में स्टोर हो सकता है — "é" एक precomposed code point के रूप में या "e" और एक combining accent के रूप में। Unicode normalization (NFC, NFD, NFKC, NFKD) इन्हें तुलनीय बनाता है, इसलिए search, uniqueness जाँच और यूज़रनेम को एकरूप तरीके से normalise करना चाहिए। लंबाई भी अस्पष्ट है: हिंदी शब्द "नमस्ते" 6 code points, 6 UTF-16 units, 18 UTF-8 bytes और 3 यूज़र को दिखने वाले अक्षर (grapheme clusters: न, म, स्ते) है। Bytes में गिनी सीमा, अक्षरों में गिनी सीमा और code point से चलने वाला cursor — तीनों अलग नतीजे देंगे।
देवनागरी virama (हलंत) के ज़रिए व्यंजनों को संयुक्ताक्षर (क्ष, स्त) में जोड़ती है, और कुछ मात्राएँ उस व्यंजन से पहले बनाई जाती हैं जिसके बाद वे मेमोरी में आती हैं — "कि" में इ की मात्रा क के बाद स्टोर होती है पर उसके बाईं ओर दिखती है। Cluster के भीतर truncation, highlighting या cursor चलाने से बिना आधार की मात्रा बचती है, जिसे rendering engine आमतौर पर बिंदीदार वृत्त (◌ि) के साथ दिखाते हैं। पूरी देवनागरी shaping सपोर्ट न करने वाला फ़ॉन्ट संयुक्ताक्षरों को दिखते हलंत के साथ अलग-अलग अक्षरों में दिखाता है।
Sorting और search locale-specific हैं: प्लेटफ़ॉर्म का collation इस्तेमाल करें (JavaScript में Intl.Collator, डेटाबेस में collations) और ऐसे नामों से टेस्ट करें जो अलिफ़ के अलग-अलग रूपों (ا أ إ آ) से शुरू हों, मात्राओं/तश्कील के साथ और बिना, और मिश्रित लिपियों में। इनपुट की अपनी जाँचें हैं: अरबी कीबोर्ड, InScript लेआउट या phonetic transliteration कीबोर्ड से टाइप की गई हिंदी, और input method editors (IME) जो कई keystrokes में टेक्स्ट compose करते हैं — हर keystroke पर चलने वाला validation composition को बीच में तोड़ सकता है।
- टेक्स्ट का फैलना और सिकुड़ना: अनुवाद अंग्रेज़ी से काफ़ी लंबा या छोटा हो सकता है, ख़ासकर छोटे labels में; बटन, टैब, टेबल हेडर, toast और badge को हर locale की असली strings से टेस्ट करें।
- ऊर्ध्वाधर जगह: देवनागरी में शिरोरेखा के ऊपर और नीचे मात्राएँ हैं और अरबी में अक्षरों के ऊपर-नीचे तश्कील; hidden overflow के साथ fixed line height इन्हें काट देती है।
- SMS: अरबी या देवनागरी वाला मैसेज आमतौर पर UCS-2 में, 16 bit प्रति अक्षर, भेजा जाता है; एक SMS में 140 octets user data होता है (3GPP TS 23.040), इसलिए एक मैसेज में GSM 7-bit alphabet के 160 की जगह 70 अक्षर आते हैं, और OTP व notification टेम्पलेट कई मैसेज में बँट सकते हैं।
आज़माएँ: Unicode डेटासेट जनरेटर आज़माएँ: स्ट्रिंग लेंथ काउंटर आज़माएँ: कैरेक्टर काउंटर आज़माएँ: स्पेशल कैरेक्टर डेटासेट जनरेटर
लोकलाइज़ेशन टेस्टिंग कैसे चलाएँ
लोकलाइज़ेशन टेस्टिंग अंत में एक दौर की बजाय gates की श्रृंखला के रूप में बेहतर काम करती है: सबसे सस्ते डिफ़ेक्ट (i18n) अनुवाद से पहले मिलते हैं, और सबसे ज़्यादा दिखने वाले (लेआउट और भाषा) के लिए अनुवाद चाहिए। एक व्यावहारिक क्रम, जो एंड-टू-एंड क्वालिटी एश्योरेंस गाइड में बताए टेस्ट स्तरों से मेल खाता है:
- Requirements और डिज़ाइन में locale फ़ैसले देखें: कौन-से locales, हर locale के लिए कौन-सा कैलेंडर और अंक, यूज़र कौन-से फ़ॉर्मेट बदल सकता है, fallback भाषा, और क्या जान-बूझकर अनुवादित नहीं होगा (ब्रांड नाम, क़ानूनी टेक्स्ट)।
- Internationalization के लिए कोड की समीक्षा करें: externalised strings, locale-aware फ़ॉर्मेटिंग API, लेआउट कोड में कोई भौतिक left/right नहीं, शुरू से अंत तक Unicode स्टोरेज।
- CI में pseudo-localization चलाएँ: हर बिल्ड pseudo-locale में चलता है, और कोई भी सादी अंग्रेज़ी string डिफ़ेक्ट है।
- हर locale में localized टेस्ट डेटा से फ़ंक्शनल टेस्टिंग करें — लक्षित लिपियों और फ़ॉर्मेट में नाम, पते, फ़ोन नंबर, रकम और तारीख़ें — हर लेयर से डेटाबेस तक और वापस export, ईमेल और SMS तक।
- मातृभाषियों के साथ संदर्भ में linguistic review करें, स्क्रीनशॉट और string keys के साथ, glossary और style guide के विरुद्ध।
- हर रिलीज़ पर रिग्रेशन: localized smoke टेस्ट, missing-key जाँच और हर बिल्ड पर हर locale की screenshot तुलना, और जब कोई फ़ीचर टेक्स्ट-भारी स्क्रीन बदले तो पूरा localization दौर।
Localization test checklist, per locale (ar-SA, hi-IN, en-US ...)
[ ] Locale is picked correctly (setting, Accept-Language, URL) and persists
[ ] Unsupported locale falls back to the agreed default, never to raw keys
[ ] No untranslated or hard-coded strings (pseudo-locale run is clean)
[ ] Plurals: counts 0, 1, 2, 3, 11, 100 give the correct Arabic forms
[ ] Dates: calendar, digits, month names, time zone, midnight shift
[ ] Numbers: digits, decimal and grouping separators, lakh/crore in hi-IN
[ ] Currency: ISO 4217 code, symbol, position, minor units, input parsing
[ ] Text: Arabic and Devanagari intact through DB, API, CSV, PDF, email, SMS
[ ] Length limits enforced in the unit the backend uses (chars vs bytes)
[ ] Sorting and search work for the locale (alif forms, diacritics)
[ ] Layout: no truncation, clipping or overlap with real strings
[ ] RTL: direction, mirroring, bidirectional text (see the RTL guide)
[ ] lang attribute on the page and on inline foreign-language textआज़माएँ: बहुभाषी टेस्ट डेटा जनरेटर आज़माएँ: अरबी टेस्ट डेटा जनरेटर आज़माएँ: हिंदी टेस्ट डेटा जनरेटर आज़माएँ: सऊदी एड्रेस टेस्ट डेटा
लोकलाइज़ेशन जाँचों का ऑटोमेशन
ऑटोमेटेड टेस्ट एक से ज़्यादा locale में चलने चाहिए। Suite को locale और time zone से parameterise करें, और assertions में फ़ॉर्मेट की गई strings टाइप करने की बजाय अपेक्षित वैल्यू प्लेटफ़ॉर्म के Intl API से निकालें — टाइप की गई strings अदृश्य marks चूक जाती हैं और CLDR डेटा अपडेट होते ही टूटती हैं। अपेक्षित वैल्यू उसी runtime में निकालें जिसने असली वैल्यू बनाई: Node.js test runner और ब्राउज़र के ICU वर्ज़न अलग हो सकते हैं और नतीजे भी।
तीन सस्ती जाँचें ज़्यादातर रिग्रेशन पकड़ लेती हैं: missing-key जाँच जो CI में हर locale फ़ाइल की source locale से तुलना करे, untranslated जाँच जो source जैसी ही वैल्यू पकड़े (ब्रांड नाम और कोड के लिए allow-list के साथ), और मुख्य स्क्रीन की हर locale में screenshot तुलना।
// Locale-parameterised UI check (Playwright Test)
for (const locale of ["en-US", "ar-SA", "hi-IN"]) {
test(`order total is formatted for ${locale}`, async ({ browser }) => {
const context = await browser.newContext({
locale,
timezoneId: locale === "hi-IN" ? "Asia/Kolkata" : "Asia/Riyadh",
});
const page = await context.newPage();
await page.goto("/orders/ORD-2026-0042");
// expected value computed with Intl in the same browser, not typed by hand
const expected = await page.evaluate(
(l) => new Intl.NumberFormat(l, { style: "currency", currency: "SAR" }).format(1500),
locale,
);
await expect(page.getByTestId("order-total")).toHaveText(expected);
await expect(page).toHaveScreenshot(`order-${locale}.png`);
});
}
// Missing and untranslated keys (Node.js, runs in CI)
const flat = (o, p = "") => Object.entries(o).flatMap(([k, v]) =>
v && typeof v === "object" ? flat(v, p + k + ".") : [[p + k, v]]);
const en = new Map(flat(require("./locales/en.json")));
const ar = new Map(flat(require("./locales/ar.json")));
const missing = [...en.keys()].filter((k) => !ar.has(k));
const same = [...en].filter(([k, v]) => ar.get(k) === v);
if (missing.length) { console.error("Missing in ar:", missing); process.exit(1); }
if (same.length) console.warn("Identical to en, check:", same.map(([k]) => k));आम लोकलाइज़ेशन डिफ़ेक्ट, बग टाइटल के रूप में
नीचे के उदाहरण समझाने के लिए हैं, असली घटनाएँ नहीं। हर एक बग रिपोर्ट के pattern — लक्षण, जगह और शर्त — पर चलता है; बाक़ी रिपोर्ट बग रिपोर्ट कैसे लिखें गाइड में है।
- Cart badge "منتجان" की जगह "2 منتج" दिखाता है — plural रूप count === 1 जाँच से चुना गया
- ऐप में अरबी चुनने वाले यूज़र्स को ऑर्डर कन्फ़र्मेशन ईमेल अंग्रेज़ी में मिलता है
- रियाद समय 00:00 से 03:00 के बीच तारीख़ चुनने पर हिजरी date picker पिछला दिन स्टोर करता है
- अरबी कीबोर्ड से टाइप किए "١٥٠٠" को रकम फ़ील्ड "Invalid number" कहकर अस्वीकार करता है
- hi-IN सेल्स रिपोर्ट 12,34,567 की जगह 1,234,567 दिखाती है
- हिंदी प्रोडक्ट नाम संयुक्ताक्षर के भीतर कटा, search नतीजों में बिंदीदार वृत्त वाली मात्रा बची
- अरबी रजिस्ट्रेशन फ़ॉर्म पर validation मैसेज "Field is required" अनुवादित नहीं
अक्सर पूछे जाने वाले सवाल
Internationalization टेस्टिंग और localization टेस्टिंग में क्या फ़र्क़ है?
Internationalization टेस्टिंग जाँचती है कि प्रोडक्ट किसी भी locale को सपोर्ट कर सकता है — externalised strings, locale-aware फ़ॉर्मेटिंग, हर जगह Unicode, तय न की गई टेक्स्ट दिशा — और यह अनुवाद से पहले pseudo-localization से सबसे अच्छी होती है। Localization टेस्टिंग एक ख़ास locale जाँचती है: संदर्भ में उसका अनुवाद, फ़ॉर्मेट, लेआउट और सांस्कृतिक उपयुक्तता।
क्या लोकलाइज़ेशन टेस्टिंग के लिए मातृभाषी चाहिए?
भाषा की गुणवत्ता के लिए हाँ: शब्दावली, व्याकरण, संबोधन और स्वाभाविकता के लिए योग्य मातृभाषी चाहिए। ज़्यादातर बाक़ी जाँचें — फ़ॉर्मेट, truncation, encoding, plural, छूटी strings, लेआउट — कोई भी टेस्टर सही टेस्ट डेटा और चेकलिस्ट के साथ कर सकता है।
Pseudo-localization क्या है?
Source strings का accent वाले, लंबे और ब्रैकेट वाले टेक्स्ट (और चाहें तो right-to-left टेक्स्ट) में स्वचालित रूपांतरण, जिसे नक़ली locale की तरह इस्तेमाल किया जाता है। यह असली अनुवाद से पहले ही hard-coded strings, concatenation, truncation और encoding समस्याएँ उजागर करता है।
सऊदी अरब के सॉफ़्टवेयर को कौन-सा कैलेंडर इस्तेमाल करना चाहिए?
यह प्रोडक्ट फ़ैसला है जो requirements में लिखा जाना चाहिए। सऊदी अरब अपने हिजरी कैलेंडर को Umm al-Qura के रूप में मानकीकृत करता है, और ग्रेगोरियन कैलेंडर भी व्यापक रूप से इस्तेमाल होता है, इसलिए कई प्रोडक्ट दोनों दिखाते हैं या यूज़र को चुनने देते हैं। जो भी चुना जाए, कोड में कैलेंडर स्पष्ट रूप से माँगें और हर runtime पर टेस्ट करें, क्योंकि डिफ़ॉल्ट CLDR वर्ज़न के साथ बदलते हैं।
अरबी में कितने plural रूप होते हैं?
Unicode CLDR के plural नियम अरबी के लिए छह cardinal श्रेणियाँ परिभाषित करते हैं: zero, one, two, few, many और other। सबको छूने के लिए 0, 1, 2, 3, 11 और 100 जैसी संख्याएँ टेस्ट करें। हिंदी में दो श्रेणियाँ हैं: one (0 और 1 के लिए) और other।
संदर्भ
- Internationalization (i18n) Activityबहुभाषी वेब कंटेंट बनाने और टेस्ट करने के लिए W3C के internationalization लेख, ट्यूटोरियल और जाँचें।
- Unicode CLDR ProjectCommon Locale Data Repository: तारीख़, समय, संख्या व मुद्रा फ़ॉर्मेट और plural नियमों का locale डेटा जिसे ज़्यादातर प्लेटफ़ॉर्म इस्तेमाल करते हैं।
- The Unicode Standardसार्वभौमिक कैरेक्टर सेट और उसके एन्कोडिंग रूप (UTF-8, UTF-16, UTF-32), नॉर्मलाइज़ेशन और हर कोड पॉइंट के गुण।
- ECMAScript Internationalization API Specification (ECMA-402)JavaScript Intl API का स्पेसिफ़िकेशन — ब्राउज़र में तारीख़, संख्या, मुद्रा, सूची और plural नियमों की locale-aware फ़ॉर्मेटिंग।
- Intl — MDNव्यवहार में Intl namespace: DateTimeFormat, NumberFormat, Collator, PluralRules और locale negotiation कैसे काम करता है।
- Time Zone Databaseदुनिया के time zone और उनके ऐतिहासिक offset व daylight-saving नियमों का tz डेटाबेस, जो साल में कई बार अपडेट होता है।
- ISO 4217 — Currency codesतीन-अक्षरी मुद्रा कोड (SAR, INR, USD…) और उनकी minor units — मुद्रा फ़ील्ड और फ़ॉर्मेटिंग टेस्ट का संदर्भ।
- RFC 5646: Tags for Identifying LanguagesBCP 47 भाषा टैग (ar, ar-SA, hi-IN, en-GB) — lang एट्रिब्यूट, Accept-Language और locale सेटिंग में इस्तेमाल होने वाले पहचानकर्ता।
- Indic Layout Requirementsदेवनागरी जैसी भारतीय लिपियों की लेआउट आवश्यकताएँ — संयुक्ताक्षर, मात्राएँ, लाइन ब्रेकिंग — हिंदी इंटरफ़ेस के लिए प्रासंगिक (W3C Working Draft)।
अभ्यास
पहले लोकलाइज़ेशन दौर के निष्कर्ष परखें
आप एक grocery delivery सेवा (काल्पनिक) टेस्ट कर रहे हैं, जिसका Android app और website दो बाज़ारों में चलते हैं: सऊदी अरब, ar-SA और अंग्रेज़ी में, SAR में क़ीमतों के साथ; और भारत, hi-IN और अंग्रेज़ी में, INR में क़ीमतों के साथ। Release 2.0 अब तक सिर्फ़ अंग्रेज़ी वाले प्रोडक्ट में अरबी और हिंदी जोड़ता है। नीचे के material में requirements से locale फ़ैसले, resource फ़ाइलों का एक अंश, और staging पर पहले localization दौर के दस observations हैं, जिनमें एक pseudo-locale run भी है।
गाइड के लोकलाइज़ेशन टेस्टिंग नक्शे और चेकलिस्ट के साथ काग़ज़ पर काम करें। Locale फ़ैसले आपका test basis हैं: हर observation को उन्हीं से परखें, और जहाँ वे कुछ नहीं कहते, वहाँ गाइड के नियमों से। स्ट्रिंग लेंथ काउंटर और कैरेक्टर काउंटर दो सवालों का जवाब देते हैं, और Timezone कन्वर्टर तीसरे में मदद करता है। इसके लिए 25–30 मिनट रखें।
Grocery delivery सेवा (काल्पनिक) - Android app और website, दो बाज़ार
सऊदी बाज़ार locales ar-SA (डिफ़ॉल्ट) और en SAR zone Asia/Riyadh (UTC+03:00)
भारतीय बाज़ार locales hi-IN (डिफ़ॉल्ट) और en INR zone Asia/Kolkata (UTC+05:30)
Release 2.0 अरबी और हिंदी जोड़ता है; अब तक सेवा सिर्फ़ अंग्रेज़ी में थी।
आज: सोमवार 12 अक्टूबर 2026। Staging, build 2.0.0-rc1, पहला localization दौर।
Locale फ़ैसले (requirements)
LOC-1 ar-SA: हर स्क्रीन पर पश्चिमी अंक (0-9) और ग्रेगोरियन तारीख़ें। ऑर्डर
confirmation में Umm al-Qura हिजरी तारीख़ भी दिखती है।
LOC-2 भारतीय बाज़ार: रकम INR में, भारतीय grouping (12,34,567) के साथ,
hi-IN और en दोनों में।
LOC-3 रकम, फ़ोन और कोड फ़ील्ड अरबी-इंडिक अंक स्वीकार करके उन्हें बदलते हैं।
LOC-4 ईमेल, SMS और push notification ऐप में चुनी गई भाषा में जाते हैं।
LOC-5 प्रोडक्ट नाम: ज़्यादा से ज़्यादा 40 अक्षर, जैसे यूज़र उन्हें देखता है।
LOC-6 Daily sales रिपोर्ट: ऑर्डर बाज़ार के स्थानीय कैलेंडर दिन के हिसाब से समूहित।
Umm al-Qura संदर्भ: 1 Rabi al-Akhir 1448 = शनिवार 12 सितंबर 2026,
1 Jumada al-Ula 1448 = सोमवार 12 अक्टूबर 2026।
Resource फ़ाइलें (अंश; delivery कोड 6 अंकों के होते हैं)
cart.items
en {count, plural, one {# item in your cart} other {# items in your cart}}
ar {count, plural,
one {منتج واحد في السلة}
other {# منتج في السلة}}
hi {count, plural, one {कार्ट में # आइटम है} other {कार्ट में # आइटम हैं}}
slot.notice
en Delivery to {area} between {from} and {to}
ar التوصيل إلى {المنطقة} بين {from} و{to}
wallet.invalidAmount
en Invalid number
ar (कोई entry नहीं)
sms.deliveryCode
en Your delivery code is {code}. Share it only with the courier at your door.
hi आपका डिलीवरी कोड {code} है। यह कोड केवल डिलीवरी पार्टनर को बताएँ, किसी और को नहीं।
Observations (staging, build 2.0.0-rc1)
O1 ar-SA, cart: 0 आइटम -> "0 منتج في السلة", 2 -> "2 منتج في السلة",
3 -> "3 منتج في السلة", 11 -> "11 منتج في السلة"।
O2 ar-SA, delivery slot स्क्रीन: "التوصيل إلى {المنطقة} بين 18:00 و20:00"।
O3 Pseudo-locale run, Android English (XA: accents, padding शब्द, brackets):
checkout बटन Place order
order summary [Ýöû šåVé one two] 15.00 SAR [öñ ţĥîš öŕðéŕ one two]
tab bar का चौथा टैब [Öŕðéŕ ĥîšţ
O4 ar-SA, wallet top-up: अरबी कीबोर्ड से टाइप किया "١٥٠" "Invalid number"
(अंग्रेज़ी में) के साथ अस्वीकार होता है; "150" स्वीकार होता है।
O5 भारतीय बाज़ार, ऐप की भाषा हिंदी, फ़ोन की भाषा अंग्रेज़ी: delivery-code SMS
अंग्रेज़ी में आता है।
O6 Admin web, हिंदी UI: प्रोडक्ट नाम "बासमती सेला चावल" इस मैसेज के साथ
अस्वीकार होता है: "नाम 40 अक्षरों से लंबा है"।
O7 मंगलवार 6 अक्टूबर 2026 की सऊदी daily sales रिपोर्ट में ऑर्डर ORD-48213 है।
ग्राहक ने इसे बुधवार 7 अक्टूबर को रियाद समय 01:30 पर दिया;
created_at 2026-10-06T22:30:00Z।
O8 ar-SA, रविवार 11 अक्टूबर 2026 को दिए गए ऑर्डर का confirmation:
"الأحد، ١١ أكتوبر ٢٠٢٦ (٢٨ ربيع الآخر ١٤٤٨ هـ)"
O9 भारतीय बाज़ार, मासिक sales रिपोर्ट का total: hi-IN "₹1,234,567.50",
en "₹12,34,567.50"। रवि (tester) ने en वैल्यू को "wrong grouping" कहकर log किया है।
O10 सऊदी बाज़ार, courier delivery slip (PDF): ग्राहक का नाम "نورة القحطاني"
"???? ????????" छपता है। Admin web वही नाम सही दिखाता है।- हर observation के लिए तय करें: क्या यह defect है (locale फ़ैसला या गाइड का नियम बताएँ), यह internationalization (i18n) defect है या localization (l10n) defect, और यह गाइड के नक्शे के किस क्षेत्र में आता है? कुछ observations में एक से ज़्यादा निष्कर्ष हैं, और एक में ऐसी रिपोर्ट है जो defect नहीं है।
- O1 के लिए सुधरा हुआ अरबी message और उसकी plural test तालिका लिखें: हर संख्या, वह CLDR श्रेणी जिसे वह छूती है, और अपेक्षित टेक्स्ट। फिर बताएँ कि हिंदी तालिका को कौन-सी संख्याएँ चाहिए।
- मापें: O6 का प्रोडक्ट नाम स्ट्रिंग लेंथ काउंटर से (वह क्यों अस्वीकार हुआ?), और O5 का हिंदी SMS, 6 अंकों के कोड के साथ, कैरेक्टर काउंटर से (उसकी लंबाई का क्या मतलब है?)।
- O7 और O8 के अपेक्षित मान निकालें: ORD-48213 किस दिन की रिपोर्ट में आना चाहिए, हर बाज़ार में कौन-से घंटे प्रभावित हैं, और 11 अक्टूबर 2026 की Umm al-Qura तारीख़।
- हर defect के लिए बग टाइटल लिखें (लक्षण, जगह, शर्त), फिर बताएँ कि defects के हर समूह को कौन-सी सबसे सस्ती, पहले की जाँच पकड़ लेती।
मॉडल उत्तर दिखाएँ
Test basis और कुल नतीजा। LOC-1 से LOC-6 test basis हैं; जहाँ वे कुछ नहीं कहते, वहाँ गाइड के नियम लागू होते हैं। दस observations में 14 defects हैं, एक रिपोर्ट जो defect नहीं है (O9 में en की grouping), और product owner के लिए एक खुला सवाल (O5 में SMS की लंबाई)। 11 defects internationalization (i18n) के हैं: वे कोड में रहते हैं — hard-coded string, concatenation, या parsing, फ़ॉर्मेटिंग या conversion का ऐसा कदम जो locale को अनदेखा करे — और उन्हें डेवलपर ठीक करता है। 3 localization (l10n) के हैं: वे एक locale की resources में रहते हैं (O1, O2 और O4 का छूटा अरबी message), और उन्हें अनुवादक ठीक करता है।
O1: l10n defect, भाषा और अनुवाद की गुणवत्ता (plural)। Message format सही है: en और hi ICU plural श्रेणियाँ इस्तेमाल करते हैं, और ICU हर संख्या के लिए CLDR श्रेणी ख़ुद चुनता है। लेकिन अरबी resource सिर्फ़ one और other देता है, इसलिए 1 के अलावा हर संख्या other पर गिरती है: 2 को द्विवचन "منتجان" चाहिए, 3 को बहुवचन "منتجات", 11 को "منتجًا" वाला रूप, और 0 को अपना अलग रूप। ar.json को गाइड की छह श्रेणियों से ठीक करें: {count, plural, zero {السلة فارغة} one {منتج واحد في السلة} two {منتجان في السلة} few {# منتجات في السلة} many {# منتجًا في السلة} other {# منتج في السلة}}। टाइटल: अरबी cart message "منتجان في السلة" की जगह "2 منتج في السلة" दिखाता है — ar cart.items में सिर्फ़ one और other रूप हैं।
ar-SA की plural test तालिका (संख्या, CLDR श्रेणी, अपेक्षित टेक्स्ट): 0, zero, "السلة فارغة"; 1, one, "منتج واحد في السلة"; 2, two, "منتجان في السلة"; 3, 10 और 103, few, "3 منتجات في السلة" (हर बार अपनी संख्या के साथ); 11 और 99, many, "11 منتجًا في السلة"; 100, 101 और 102, other, "100 منتج في السلة"। हिंदी तालिका को अपनी दोनों श्रेणियाँ चाहिए: 0 और 1 one को छूते हैं ("कार्ट में 1 आइटम है"), और 2 और 5 जैसी दो संख्याएँ other को ("कार्ट में 2 आइटम हैं")। हिंदी में 0 one रूप लेता है, इसलिए अनुवादक से पूछें कि "कार्ट में 0 आइटम है" स्वाभाविक लगता है या नहीं, या =0 {कार्ट ख़ाली है} जैसा exact case जोड़ें।
O2: l10n defect, भाषा और अनुवाद की गुणवत्ता (message parameters)। अनुवादक ने parameter का नाम {area} अनुवाद करके {المنطقة} कर दिया। ऐप area नाम की वैल्यू भेजता है, इसलिए formatter को {المنطقة} के लिए कोई वैल्यू नहीं मिलती और वह braces जैसे के तैसे छाप देता है। ar.json ठीक करें ताकि message में {area} बिना बदले रहे। फिर यही समस्या हर जगह खोजें: एक automated जाँच जो देखे कि हर अनुवाद में ठीक वही placeholders हैं जो अंग्रेज़ी source में हैं, ऐसे सारे messages एक साथ पकड़ लेती है। टाइटल: ar-SA में delivery slot notice इलाक़े के नाम की जगह कच्चा "{المنطقة}" दिखाता है — slot.notice में parameter का नाम अनुवादित है।
O3: तीन i18n defects, जो किसी के अनुवाद पढ़ने से पहले ही मिल गए, ठीक वैसे जैसे गाइड की pseudo-localization तालिका बताती है: दो भाषा और अनुवाद की गुणवत्ता में (hard-coded string, जोड़कर बना वाक्य) और एक लेआउट में (टेक्स्ट का फैलना)। सादी अंग्रेज़ी में "Place order" hard-coded है: यह कभी resource फ़ाइलों से नहीं गुज़रा और अरबी व हिंदी में भी अंग्रेज़ी ही रहेगा। Order summary में रकम के आसपास ब्रैकेट वाले दो टुकड़े हैं: वाक्य "You save", रकम और "on this order" को जोड़कर बना है; इसके लिए parameter वाला एक message चाहिए, जैसे You save {amount} on this order, और रकम locale के हिसाब से फ़ॉर्मेट हो। चौथे टैब का closing ब्रैकेट ग़ायब है: label कटा है, यानी लंबे अनुवादों के लिए जगह नहीं; tab bar को असली अरबी और हिंदी labels के साथ भी जाँचें। टाइटल: "Place order" बटन का टेक्स्ट hard-coded है, resource फ़ाइलों में नहीं; order summary की "You save … on this order" लाइन concatenation से बनी है; pseudo-locale में चौथे टैब (Order history) का label कटा है।
O4: दो defects। पहला i18n, locale फ़ॉर्मेट (संख्याएँ और अंक): LOC-3 कहता है कि अरबी-इंडिक अंक स्वीकार करके बदले जाएँ, और फ़ील्ड उन्हें अस्वीकार करता है। फ़ोन और कोड फ़ील्ड भी टेस्ट करें, जिन्हें LOC-3 कवर करता है, और product owner से पूछें कि अरबी दशमलव separator स्वीकार है या नहीं (١٥٠٫٥٠)। दूसरा l10n, भाषा और अनुवाद की गुणवत्ता (अनअनुवादित string): wallet.invalidAmount en.json में है पर ar.json में नहीं, इसलिए ऐप अंग्रेज़ी पर fallback करता है। Missing-key जाँच ऐसी हर key पकड़ती है: गाइड की script उनकी वजह से CI बिल्ड fail करती है, और en.json और ar.json के बीच JSON डिफ़ उन्हें हटाई गई keys के रूप में दिखाता है (हर अनुवादित वैल्यू बदली हुई दिखती है)। टाइटल: ar-SA में wallet top-up का रकम फ़ील्ड अरबी-इंडिक अंकों में टाइप किए "١٥٠" को अस्वीकार करता है; ar-SA की wallet top-up स्क्रीन पर validation मैसेज "Invalid number" अनुवादित नहीं।
O5: i18n defect, locale चयन: LOC-4 ऐप में चुनी गई भाषा माँगता है, पर SMS फ़ोन की भाषा के पीछे चलता है। हिंदी टेम्पलेट मौजूद है, इसलिए यह छूटा अनुवाद नहीं: SMS सेवा को यूज़र की ऐप भाषा मिलती ही नहीं। उसी यूज़र के लिए ईमेल और push notification जाँचें, और उन अरबी यूज़र्स को भी जिनके फ़ोन की भाषा अंग्रेज़ी है। फिर 6 अंकों के कोड वाला हिंदी SMS कैरेक्टर काउंटर में मापें: SMS (Unicode) बार 82 / 70 दिखाता है, यानी 12 ज़्यादा, क्योंकि वह UTF-16 units गिनता है (कैरेक्टर वाली गिनती कम है, क्योंकि वह grapheme clusters गिनती है)। देवनागरी टेक्स्ट आमतौर पर UCS-2 में भेजा जाता है, जहाँ एक मैसेज में 70 अक्षर (UTF-16 units) आते हैं, इसलिए यह SMS दो मैसेज में जाता है; अंग्रेज़ी टेक्स्ट, GSM 7-bit alphabet में 74 अक्षर (74 / 160), एक में आ जाता है। कोई requirement सीमा तय नहीं करती, इसलिए यह failure नहीं: इसे product owner के लिए सवाल के रूप में उठाएँ, क्योंकि providers आमतौर पर हर हिस्से को अलग मैसेज गिनते हैं, और 70 अक्षरों तक का हिंदी विकल्प सुझाएँ। टाइटल: जिन यूज़र्स की ऐप भाषा हिंदी और फ़ोन की भाषा अंग्रेज़ी है, उन्हें delivery-code SMS अंग्रेज़ी में भेजा जाता है।
O6: i18n defect, टेक्स्ट और लिपि हैंडलिंग (लंबाई)। स्ट्रिंग लेंथ काउंटर 11 grapheme clusters, 16 code points, 16 UTF-16 units और 44 UTF-8 bytes देता है। सिर्फ़ bytes की गिनती 40 से ऊपर है, इसलिए जाँच UTF-8 bytes गिनती है, जबकि LOC-5 वे अक्षर गिनता है जो यूज़र देखता है, यानी grapheme clusters: नाम स्वीकार होना चाहिए। 40 और 41 grapheme clusters वाले देवनागरी नामों से boundary टेस्ट जोड़ें, और पूछें कि डेटाबेस कॉलम कौन-सी इकाई और आकार इस्तेमाल करता है, क्योंकि 40 clusters वाले हिंदी नाम में code points कहीं ज़्यादा हो सकते हैं, और हर एक के लिए UTF-8 में तीन bytes तक। टाइटल: Admin का प्रोडक्ट फ़ॉर्म 11 अक्षरों का हिंदी प्रोडक्ट नाम "40 अक्षरों से लंबा" कहकर अस्वीकार करता है — सीमा UTF-8 bytes में गिनी जाती है।
O7: i18n defect, locale फ़ॉर्मेट (समय और time zone)। 2026-10-06T22:30:00Z रियाद में बुधवार 7 अक्टूबर का 01:30 है (UTC+03:00), जैसा Timezone कन्वर्टर दिखाता है। रिपोर्ट ऑर्डरों को UTC तारीख़ से समूहित करती है, जबकि LOC-6 बाज़ार का स्थानीय दिन माँगता है, इसलिए ORD-48213 की जगह 7 अक्टूबर की रिपोर्ट है। प्रभावित हैं रियाद समय 00:00 से 02:59 के बीच दिए गए सारे ऑर्डर, और भारतीय बाज़ार में कोलकाता समय 00:00 से 05:29 के बीच के (UTC+05:30)। सीमाओं पर टेस्ट डेटा: रियाद में 02:59 और 03:00, कोलकाता में 05:29 और 05:30, और दोनों बाज़ारों में स्थानीय 23:59 और 00:00; हर दिन का total उस दिन के ऑर्डरों के जोड़ से मिलाएँ। टाइटल: सऊदी daily sales रिपोर्ट रियाद समय 00:00 से 02:59 के बीच के ऑर्डर पिछले दिन में दिखाती है — ऑर्डर UTC तारीख़ से समूहित।
O8: locale फ़ॉर्मेट (तारीख़ और कैलेंडर) में दो i18n defects। पहला, अंक अरबी-इंडिक हैं जबकि LOC-1 पश्चिमी अंक माँगता है। सबसे संभव है कि कोड सिर्फ़ ar-SA माँगता है, जिसका नए CLDR डेटा में डिफ़ॉल्ट अरबी-इंडिक अंक है; उसे numbering system स्पष्ट रूप से माँगना होगा (ar-SA-u-nu-latn, और हिजरी तारीख़ के लिए ar-SA-u-ca-islamic-umalqura-nu-latn), और हर उस runtime पर टेस्ट होना होगा जो तारीख़ें फ़ॉर्मेट करता है: ईमेल और PDF के लिए सर्वर, Android और ब्राउज़र। दूसरा, हिजरी तारीख़ ग़लत है। 1 Rabi al-Akhir 1448 = 12 सितंबर और 1 Jumada al-Ula = 12 अक्टूबर, इसलिए 11 अक्टूबर Rabi al-Akhir का आख़िरी दिन है: दिन 30, यानी 12 सितंबर के 29 दिन बाद। 28 वह है जो tabular civil हिजरी गणना (ICU का islamic-civil कैलेंडर) उस दिन के लिए देती है, यानी कोड Umm al-Qura की जगह कोई दूसरी गणना इस्तेमाल करता है। अपेक्षित: "الأحد، 11 أكتوبر 2026 (30 ربيع الآخر 1448 هـ)"। टेस्ट डेटा में दोनों कैलेंडर के महीनों के अंत और एक साल का अंत जोड़ें। टाइटल: ar-SA ऑर्डर confirmation तारीख़ें पश्चिमी अंकों की जगह अरबी-इंडिक अंकों में दिखाता है; ऑर्डर confirmation 11 अक्टूबर 2026 के लिए हिजरी तारीख़ 28 Rabi al-Akhir 1448 दिखाता है, Umm al-Qura की 30 Rabi al-Akhir 1448 नहीं।
O9: एक defect और एक अमान्य रिपोर्ट। LOC-2 के तहत hi-IN को ₹12,34,567.50 दिखाना चाहिए; ₹1,234,567.50 पश्चिमी grouping है, यानी रिपोर्ट hi-IN रकम किसी दूसरे locale या तय pattern से फ़ॉर्मेट करती है (i18n, locale फ़ॉर्मेट)। en की वैल्यू, ₹12,34,567.50, ठीक वही है जो LOC-2 भारतीय बाज़ार के लिए माँगता है: रवि की रिपोर्ट को "works as specified" कहकर reject करें और LOC-2 उद्धृत करें। टाइटल: hi-IN मासिक sales रिपोर्ट ₹12,34,567.50 की जगह ₹1,234,567.50 दिखाती है।
O10: i18n defect, टेक्स्ट और लिपि हैंडलिंग (encoding)। प्रश्नचिह्नों का मतलब है कि अक्षर ऐसे encoding में conversion के दौरान खो गए जिसमें अरबी अक्षर नहीं हैं; glyph के बिना फ़ॉन्ट ख़ाली बॉक्स दिखाता, और single-byte encoding में पढ़ा गया UTF-8 "Ø" जैसा लैटिन कचरा दिखाता। हर अक्षर के लिए एक प्रश्नचिह्न (4 और 8) इसी नुक़सान से मेल खाता है। Admin web नाम सही दिखाता है, इसलिए स्टोर की गई वैल्यू शायद ठीक है और नुक़सान PDF तक के रास्ते में होता है: slip सेवा में या उसकी PDF library में। भारतीय बाज़ार की slip पर हिंदी नाम और मिश्रित लिपि वाला नाम भी टेस्ट करें। टाइटल: Courier delivery slip (PDF) अरबी ग्राहक नामों को प्रश्नचिह्नों के रूप में छापती है।
सबसे सस्ती, पहले की जाँचें। CI में pseudo-localization पहले ही बिल्ड पर, किसी अनुवाद से पहले, O3 का सब कुछ पकड़ लेता। Resource फ़ाइलों पर automated जाँचें अनुवाद आने के दिन ही l10n defects पकड़ लेतीं: छूटी keys (O4), source से अलग placeholders (O2), और लक्ष्य भाषा की सारी CLDR श्रेणियों के बिना plural messages (O1)। बाक़ी i18n defects (O4 की अंक parsing, और O5 से O10) locale को अनदेखा करने वाला कोड हैं: internationalization के लिए code review उन्हें पकड़ता है, और किसी भी manual दौर से पहले localized टेस्ट डेटा वाले हर locale के फ़ंक्शनल टेस्ट भी — अरबी-इंडिक अंक, देवनागरी नाम, आधी रात के पास के समय, Umm al-Qura महीने का अंत, बड़ी INR रकम, PDF और SMS तक पहुँचते अरबी और हिंदी नाम; इन टेस्ट को regression टेस्ट के रूप में रखें। SMS की लंबाई requirements review का हिस्सा है: हर टेम्पलेट और भाषा के लिए अधिकतम लंबाई।
अगर आपके जवाब अलग हैं, तो उन्हें गाइड के दो नियमों से मिलाएँ: i18n defect कोड में रहता है और डेवलपर उसे ठीक करता है, l10n defect एक locale के कंटेंट में रहता है और उसी resource में ठीक होता है; और कोई observation तभी defect है जब वह locale फ़ैसलों या गाइड के बताए किसी नियम के ख़िलाफ़ हो। O8 या O9 को l10n कहना, क्योंकि वे एक ही locale में दिखते हैं, स्वीकार्य है अगर आपकी रिपोर्ट सुधार कोड में रखे; O9 की en grouping या O5 की SMS लंबाई को failure बताना स्वीकार्य नहीं।
इस topic में आपकी प्रगति
प्रगति ट्रैक करने के लिए साइन इन करें
Topics पूर्ण चिह्नित करें, जहाँ छोड़ा था वहीं से जारी रखें और specialisation परीक्षाएँ खोलें।
QA रोडमैप का हिस्सा
इस topic से पहले
अगले topics
इस गाइड में बताए गए टूल्स
लोकलाइज़ेशन टेस्टिंग के लिए अरबी नाम, पते, वाक्य, संख्याएँ (अरबी-हिंदसी अंक) और RTL edge case जनरेट करें।
लोकलाइज़ेशन टेस्टिंग के लिए हिंदी (देवनागरी) नाम, पते, वाक्य और अंक जनरेट करें।
i18n और RTL/LTR मिश्रण जाँचने के लिए एक ही रिकॉर्ड कई भाषाओं (अंग्रेज़ी, अरबी, हिंदी और अन्य) में जनरेट करें।
कई लिपियों (अरबी, देवनागरी, CJK, सिरिलिक), emoji, संयोजक चिह्न और normalisation रूपों में Unicode टेस्ट स्ट्रिंग जनरेट करें।
तारीख़ों के डेटासेट जनरेट करें: किसी रेंज में रैंडम तारीख़ें, leap day, महीने के अंत, DST किनारे और कई फ़ॉर्मेट।
तारीख़ और समय को अलग-अलग timezone के बीच बदलें (रियाद, अम्मान, दिल्ली, UTC, न्यूयॉर्क, लंदन…)।
स्ट्रिंग की लंबाई कैरेक्टर, कोड पॉइंट, UTF-8 बाइट और UTF-16 यूनिट में मापें।
सऊदी National Address जैसा टेस्ट डेटा जनरेट करें: बिल्डिंग नंबर, स्ट्रीट, ज़िला, शहर, पोस्टल कोड और additional number।
स्पेशल कैरेक्टर से भरे इनपुट जनरेट करें: कोट, SQL/HTML/JSON मेटाकैरेक्टर, कंट्रोल कैरेक्टर, emoji और path की चालाकियाँ।
दो JSON डॉक्यूमेंट की सिमैंटिक तुलना करें और जोड़ी गई, हटाई गई तथा बदली गई वैल्यू हाइलाइट करें।