نسخه فارسی برنامه باز میشود، همه صفحهها Render میشوند و Smoke test سبز است؛ اما پیام زمان ارسال هنوز انگلیسی است، مبلغ بدون واحد پول نمایش داده میشود، Placeholder اضافی نام کاربر را وارد پیام امنیتی میکند و متن شبهبومیشده از پنج Container بیرون میزند. تست i18n و l10n باید این خطاهای خاموش را پیش از انتشار Locale آشکار کند، نه اینکه فقط نبود Crash را تأیید کند.
این راهنما، Internationalization و Localization را به یک Release system قابل آزمون تبدیل میکند: Locale Contract، Language Tag، resource schema، placeholder/plural/select، fallback، Unicode/Normalization/Bidi، format/parse، pseudo-localization، translation pipeline، linguistic QA، matrix، accessibility، SEO، monitoring و Release Gate. مثالها به فارسی و RTL توجه دارند، اما صفحه مالک مهندسی انتشار چند Locale است؛ چکلیست عمیق فارسی در صفحه تخصصی خود باقی میماند.
مرز ادعا: تست میتواند برای Locale، Build، resource bundle، platform و Scenario مشخص Evidence بسازد؛ پذیرش بازار، درآمد، وفاداری، احترام فرهنگی، نبود توهین، انطباق قانونی یا «محصول بینقص جهانی» را تضمین نمیکند. زبان، لحن، Terminology، بازار، قانون، فرمت، Content و Risk باید توسط صاحبان صلاحیت همان محصول تعیین و نسخهدار شوند.
خلاصه عملی تست i18n و l10n
| پرسش | شاهد ضعیف | شاهد بهتر |
|---|---|---|
| آیا Locale آماده است؟ | برنامه Crash نکرد | key/schema/placeholder/plural/fallback audit + functional/visual/linguistic evidence |
| آیا ترجمه کامل است؟ | در TMS صددرصد است | bundle همان Build، همه Surfaceها، runtime keys و fallback telemetry بررسی شدهاند |
| آیا RTL درست است؟ | کل صفحه mirror شد | layout direction، semantic icons، mixed content، Bidi isolation و task paths آزمودهاند |
| آیا عدد/تاریخ محلی درست است؟ | ظاهر آشنا است | canonical value، locale/timezone/calendar/numbering system و parse policy trace میشوند |
| آیا متن خوب است؟ | Machine translation روان به نظر میرسد | reviewer واجد Context، glossary/style/terminology، in-context evidence و sign-off دارد |
| آیا Release آماده است؟ | Base locale سبز است | risk-based locale/platform matrix، Unknownها، fallback و rollback/monitoring روشناند |
i18n، l10n، Translation و G11n را تفکیک کنید
| مفهوم | تمرکز | Artifact نمونه | اشتباه رایج |
|---|---|---|---|
| Internationalization / i18n | توان مهندسی برای چند زبان/Locale | resource API، Unicode، formatting، layout | کار یکباره ابتدای معماری |
| Localization / l10n | تطبیق یک Release برای Locale/Market مشخص | bundle، assets، formats، content، rules | فقط ترجمه رشته |
| Translation | انتقال معنای متن میان زبانها | target messages و review | معادل کل Localization |
| Transcreation | بازآفرینی هدف/لحن در Context مجاز | campaign/content variant | مجاز برای متن حقوقی یا فنی بدون approval |
| Globalization / g11n | Operating model چندبازار/چندLocale | portfolio، governance، release calendar | نام دیگری برای UI translation |
| Linguistic QA | معنا، grammar، terminology، tone در Context | finding + reviewer decision | جایگزین functional testing |
i18n پس از افزودن نخستین Locale تمام نمیشود. Feature جدید، library upgrade، component تازه، API یا متن runtime میتواند regression بسازد. l10n نیز برای هر تغییر محتوا، rule، asset، platform و بازار نیازمند impact analysis است؛ لازم نیست همه Testها همیشه تکرار شوند، اما تصمیم selection باید traceable باشد.
صفحه ۱۸۱۸ چه چیزی را مالک است؟
صفحه حاضر مالک مهندسی و Quality Gate انتشار چندLocale است: Source message→resource schema→translation→bundle→runtime selection→format/render/input→review→release/monitoring. راهنمای تست فارسی و RTL مالک جزئیات خاص فارسی، قلم، ارقام، تقویم، UI و چکلیست بومی است.
Compatibility، Accessibility، Usability، Privacy، Integration و Ecommerce ownerهای جدا دارند. در این مقاله فقط مرز اتصال آنها با Locale release مشخص میشود تا یک چکلیست بیپایان و تکراری ساخته نشود.
Locale مساوی Language یا Country نیست
Language به زبان محتوا اشاره میکند؛ Script شیوه نوشتن؛ Region میتواند تفاوت کاربرد را مشخص کند؛ Locale در برنامه معمولاً مجموعهای از ترجیحات و قواعد مانند زبان، script، region، numbering system، calendar، collation و formats است؛ Market نیز eligibility، قیمت، قانون و عملیات تجاری را میافزاید. این مفاهیم همپوشاناند، اما قابل جایگزینی نیستند.
| شناسه | چه میگوید؟ | چه چیزی را لزوماً نمیگوید؟ |
|---|---|---|
| `fa` | زبان فارسی | کشور، timezone، calendar، currency یا قانون |
| `fa-IR` | فارسی با Region ایران | تنظیمات قطعی همه کاربران یا market eligibility |
| `sr-Latn-RS` | صربی، script لاتین، Region صربستان | ترجیحات فردی دیگر |
| Asia/Tehran | شناسه timezone | Language/Locale یا calendar |
| IRR | کد Currency در Contract مربوط | واحد نمایشی تومان یا price policy |
| Market=IR | برچسب داخلی بازار اگر تعریف شده | خودکار Language/Locale یا شمول قانونی |
RFC 5646 / BCP 47 ساخت و معنای Language Tagها را تعریف میکند. Tag سفارشی مانند `fa_IR` را بدون Contract interchange نسازید؛ در BCP ۴۷ separator و subtags قواعد مشخص دارند. بااینحال BCP ۴۷ بهتنهایی Locale runtime کامل محصول را تعیین نمیکند.
Locale Contract را نسخهدار کنید
Locale Contract localeId: internal canonical identifier languageTag: BCP 47 tag for content/language use language / script / region: explicit subtags where relevant textDirection: ltr | rtl | context-dependent policy fallbackChain: exact ordered list + allowed surfaces numberingSystem: default/allowed options decimal/grouping: display and input policy calendar/timezone: display, parse and canonical-storage rules currency/units: market/business contracts, not guessed collation/search: versioned library/rules and expectations names/addresses/phone: model and validation owners resourceVersion: source/bundle/schema/tool versions marketEligibility: independent decision/reference contentOwners: linguistic/legal/product/domain roles platformScope: web/iOS/Android/email/PDF/... knownLimitations: unsupported or fallback paths releaseOwner/expiry: decision and review date
اگر کاربر language را عوض میکند اما timezone یا currency ثابت میماند، محصول باید این استقلال را مدل کند. «Locale switch» که همه تنظیمات را بیصدا تغییر میدهد میتواند تاریخ، مبلغ یا Content نامربوط نشان دهد.
Negotiation و Selection را تعیینپذیر کنید
Locale ممکن است از preference حساب، setting دستگاه، browser header، URL، cookie، market یا default بیاید. اولویت و persistence باید صریح باشد؛ در غیر این صورت یک redirect loop یا Locale ناخواسته ساخته میشود.
Locale Selection Contract Inputs: URL, account preference, session, device/browser, market Precedence: exact ordered decision table Supported set: versioned locale registry Matching: exact → defined parent/fallback → default Persistence: account/session/device scope Explicit user choice: must not be silently overridden Unsupported tag: deterministic fallback + telemetry URL/canonical: locale routing and indexability policy API: Accept-Language/request field vs response Content-Language Cache: locale included in key/Vary strategy where applicable Logout/new device: expected reset/persistence Privacy: no unnecessary location inference
| Scenario | تزریق | Invariant |
|---|---|---|
| Preference conflict | URL=fa، account=en، browser=ar | precedence documented and visible |
| Unsupported locale | `fa-X-private` یا malformed | safe deterministic behavior؛ no crash/cache poison |
| Anonymous→login | guest fa، account en | merge/switch policy explicit |
| Two tabs | Locale در Tab A عوض میشود | scope/persistence طبق Contract |
| Cache | same URL، two Locale requests | content mix/leak رخ ندهد |
| Deep link | صفحه Locale ناموجود | route/fallback بدون از دسترفتن context |
| Explicit choice | Geo/IP پیشنهاد دیگری میدهد | user choice silently overridden نشود |
Resource Key را API پایدار ببینید
Key فقط نام فایل نیست؛ رابط میان Code، Source content، Translation memory، screenshots و Runtime است. تغییر یا reuse بیقاعده یک Key میتواند ترجمه قدیمی با معنای جدید را بدون خطا نمایش دهد. Key باید owner، context، lifecycle و source hash داشته باشد.
Message Resource Contract key: semantic stable identifier sourceMessage: approved base content description: intent, screen, actor, tone, constraints placeholders: name + type + example + sensitivity plural/select: categories/variables and examples markup policy: allowed tags/escaping/rich-text model length/visual hint:informative, not a forced truncation target owner/domain: product/legal/security/marketing/... sourceVersion/hash:change detection status: draft/reviewed/approved/deprecated screenshots/links: in-context references fallbackAllowed: yes/no and consequence security/privacy: secrets/PII prohibition or controls
- Key گمشده، اضافی، duplicate و deprecated scan شوند.
- Source تغییرکرده ترجمه قبلی را نیازمند review کند.
- یک Key برای دو معنای متفاوت reuse نشود.
- یک جمله به قطعات کوچک وابسته به ترتیب انگلیسی شکسته نشود.
- Context، gender/plural/select و placeholder examples در TMS برسند.
- HTML/Markdown/Rich text بهصورت امن و ساختاری مدیریت شود.
- Runtime-generated key بدون inventory/coverage پنهان نماند.
Placeholder را بخشی از Schema بدانید
Translator باید بتواند Placeholder را جابهجا کند، اما نباید نام، type یا تعداد آن را بیقاعده تغییر دهد. String concatenation ترتیب زبان مبدأ را تحمیل میکند و escaping یا Bidi را نیز سخت میسازد.
| Failure | مثال ساختگی | Gate |
|---|---|---|
| Missing placeholder | Base `{amount} {currency}`، target فقط `{amount}` | schema error |
| Extra placeholder | Target `{code}` و `{name}`، base فقط `{code}` | schema/security review |
| Rename | `{orderId}`→`{id}` | compile/runtime validation fail |
| Type mismatch | Date به Number formatter | typed contract test |
| Unsafe markup | translator-controlled tag/URL | allowlist/escape fail |
| Secret placeholder | Token/OTP در analytics یا screenshot | data policy violation |
| Concatenation | نام + فعل + عدد از سه Key | whole-message redesign |
Plural، Select و Grammar را از `count != ۱` نگیرید
زبانها تعداد Category و رفتار یکسان ندارند؛ fractional value و visible trailing zero نیز ممکن است Category را تغییر دهند. CLDR Categoryها نامهای `zero`، `one`، `two`، `few`، `many` و `other` دارند، اما هر Locale زیرمجموعه و Rule خودش را دارد.
صفحه رسمی CLDR Plural Rules توضیح میدهد Categoryها بر اساس تغییر لازم در عبارت انتخاب میشوند و اعداد صحیح/کسری باید آزمایش شوند. CLDR نسخهپذیر است؛ library/data version را pin کنید و Category را با intuition انگلیسی اختراع نکنید.
- ۰، ۱، ۲، مرزهای rule، teenها و مقادیر بزرگ؛
- ۱ در برابر ۱٫۰ و مقادیر کسری طبق Locale/formatter؛
- negative، NaN/Infinity فقط اگر Domain اجازه دهد؛
- `other` اجباری و fallback behavior؛
- Ordinal در برابر Cardinal؛
- Select برای gender/role/state فقط با مدل و Privacy مناسب؛
- Nested select/plural و placeholder preservation؛
- Upgrade CLDR و migration ترجمهها.
Fallback را ویژگی پنهان نکنید
Fallback میتواند availability را حفظ کند، اما کیفیت و حتی ایمنی معنا را پنهان کند. پیام Marketing شاید بتواند موقتاً به English برگردد؛ متن Legal، Transaction authorization یا emergency instruction ممکن است اجازه نداشته باشد. Policy باید per-domain و per-key باشد.
Fallback Contract Requested locale: ___ Resolution chain: exact ordered locales Per-domain allowance: UI / legal / security / transactional / help Missing-key behavior: fallback / placeholder / fail build / hold feature Visual marker: test-only or production behavior Telemetry: key, requested/resolved locale, build/bundle version Alert thresholds: by criticality, not global count only Cache behavior: requested and resolved locale identity User disclosure: if language mix affects understanding Expiry/action: owner and translation SLA
یک Smoke test که فقط `text.length > ۰` را میسنجد، Fallback ناخواسته را Pass میکند. Test باید requested locale و resolved resource source را جدا Assert کند.
Pseudo-localization را چند Mode اجرا کنید
Pseudo-localization ترجمه زبانی نیست و quality متن مقصد را نمیسنجد. یک Transformation deterministic روی Source است که hardcoded string، truncation، encoding، font، RTL و concatenation را زود آشکار میکند. یک Mode واحد همه Failureها را پیدا نمیکند.
| Mode | Transformation | کشف احتمالی | محدودیت |
|---|---|---|---|
| Accented | ASCII letters→accented Unicode | encoding/font/hardcoded | CJK/complex shaping را مدل نمیکند |
| Expansion | padding proportional + brackets | fixed width/truncation | درصد جهانی برای همه رشتهها نیست |
| RTL pseudo | direction/context transformation | layout/mirroring/Bidi issues | زبان RTL واقعی نیست |
| Bracketing | `[!! message !!]` | truncation/missing resource | visual only |
| Placeholder stress | long/mixed-dir sample values | schema/Bidi/overflow | production data distribution نیست |
| Missing-resource mode | disable fallback/mark missing | coverage gap | production policy ممکن است متفاوت باشد |
- Placeholders، markup و escape sequence دستنخورده بمانند.
- Transformation با seed/version ثابت و Artifact قابل بازتولید باشد.
- Screenshot diff با masks و baseline owner همراه شود.
- Hardcoded scanner exceptionها owner/expiry داشته باشند.
- Backend، Email، PDF، Push و validation message نیز پوشش داده شوند.
- False positive از Product name، SKU یا user content طبقهبندی شود.
Unicode را مساوی UTF-۸ ندانید
UTF-۸ یک encoding رایج برای Unicode است؛ درست بودن آن بهتنهایی grapheme، normalization، collation، case، width، emoji، Bidi یا security را حل نمیکند. Text باید در database، API، queue، cache، search index، log، export و file round-trip آزموده شود.
| ناحیه | Fixture | Oracle |
|---|---|---|
| Encoding round-trip | چند Script، combining marks، emoji | code points/graphemes preserved per contract |
| Length | emoji sequence/combining mark | UI/user limit بر grapheme؛ storage limit بر bytes/code units طبق policy |
| Truncation | multi-code-point grapheme | نیمه glyph/invalid sequence ساخته نشود |
| Search/equality | canonically equivalent strings | normalization policy consistent |
| Identifier | confusable/mixed scripts | security/domain policy؛ no blind normalization |
| Export/import | CSV/JSON/PDF/filename | encoding/declaration/round-trip روشن |
| Logs | control/newline/bidi chars | safe rendering and forensic integrity |
Normalization را بر اساس Domain انتخاب کنید
Unicode چند نمایش canonically equivalent دارد. NFC/NFD equivalence را حفظ میکنند؛ NFKC/NFKD برخی تفاوتهای compatibility را از بین میبرند و نباید کورکورانه روی متن دلخواه اعمال شوند. Identifier، Password، Search، Display و Signature نیاز یکسان ندارند.
Unicode Standard Annex #15 چهار Normalization Form و محدودیت Compatibility normalization را تعریف میکند و مجموعه Conformance test دارد. Product باید تعیین کند کجا normalize، کجا preserve و کجا compare میکند؛ QA نتیجه را با همان Contract میسنجد.
- ورودی normalized و unnormalized نتیجه Business یکسان یا متفاوت طبق policy؛
- concatenation پس از normalization دوباره بررسی شود؛
- database uniqueness و search index policy همراستا باشند؛
- امضا/hash/token روی representation دقیق و بدون mutation ناخواسته؛
- Compatibility folding برای شناسه فقط با threat/domain review؛
- ی/ی و ک/ک replacement را با Unicode normalization رسمی یکی نگیرید؛ این mapping بومی جداست.
Bidi و RTL: نمایش بصری با ترتیب منطقی فرق دارد
متن فارسی میتواند SKU، URL، Email، شماره، Currency و کد LTR داشته باشد. Unicode Bidirectional Algorithm ترتیب نمایشی را تعیین میکند، اما component و markup باید context مناسب بدهند. تغییر رشته ذخیرهشده برای «درستکردن ظاهر» میتواند copy/paste، search یا signature را بشکند.
Unicode Standard Annex #9 الگوریتم Bidi جاری را تعریف میکند. در HTML/XML، راهنمای W3C درباره Bidi markup و controls استفاده از markup و isolation برای محدودههای با جهت متفاوت را توضیح میدهد. Control character را بدون visibility/security policy در داده تزریق نکنید.
| Component | Mixed content fixture | بررسی |
|---|---|---|
| Order reference | `سفارش ORD-SYN-۴۲` | isolation، visual/copy order |
| Amount | `۱۲۰۰۰۰ IRR` در جمله فارسی | sign/currency/number grouping |
| URL/Email | LTR identifier + punctuation | click target، copy/paste، truncation |
| Code/OTP | digits+letters | logical order، no secret log |
| Breadcrumb | RTL labels + directional separators | navigation meaning, not blind mirror |
| Icon | Back/Play/Refresh/Brand | semantic mirroring per icon |
| Input | cursor/select/delete in mixed text | logical editing behavior |
همهچیز را Mirror نکنید
Reading order، navigation placement و directional affordance ممکن است Mirror شوند؛ اما لوگو، media controls، clock، chart axis، map، mathematical notation، device image و بعضی iconها context خاص دارند. Mirroring matrix را component-level و با Design owner بسازید.
| دسته | رفتار نمونه | Oracle owner |
|---|---|---|
| Layout flow | اغلب direction-aware | Design system/i18n |
| Back/Forward arrows | به navigation semantics وابسته | UX/platform |
| Play/Volume/Refresh | معمولاً universal orientation | Design/accessibility |
| Brand/logo | بدون تغییر مگر asset مصوب | Brand |
| Chart/timeline | data semantics تعیین میکند | Domain/data visualization |
| Number/formula/code | logical LTR segments often isolated | Domain/i18n |
| Image with text | localized asset یا حذف embedded text | Content/design |
Format و Parse را از Storage جدا کنید
Storage و API بهتر است canonical contract داشته باشند؛ UI میتواند Locale-aware format کند. Parse ورودی سختتر است: چند separator، digit set یا calendar ممکن است ambiguous باشند. «هر چیزی را قبول کن» داده اشتباه میسازد؛ policy باید accepted formats، ambiguity و error را تعیین کند.
| نوع | Canonical | Display/Input context | خطر |
|---|---|---|---|
| Number | typed numeric value | group/decimal/digits | `1,234` ambiguous |
| Money | amount+currency+scale | symbol/name/order/digits | symbol alone ambiguous |
| Instant | UTC/offset-aware timestamp | timezone/calendar/pattern | local time ambiguity |
| Date-only | domain date value | calendar and locale display | UTC conversion shifts date |
| Unit | value+unit code | localized name/symbol/spacing | conversion/rounding |
| Percent | ratio or percent contract | symbol/scale/order | ×100 mismatch |
| Phone/address | structured domain model | market-specific input/display | country assumptions |
Date، Timezone و Calendar را سه مفهوم بدانید
Locale تاریخ را نمایش میدهد، timezone instant را به زمان محلی تبدیل میکند و calendar شیوه نامگذاری/محاسبه تاریخ را تعیین میکند. `fa-IR` بهتنهایی نگفته کاربر حتماً Asia/Tehran یا یک Calendar خاص میخواهد. محصول باید default و انتخابها را مشخص کند.
- instant نزدیک نیمهشب در چند timezone؛
- date-only بدون تبدیل ناخواسته به UTC؛
- DST تاریخی/آینده طبق tzdata نسخهدار، حتی اگر بازار جاری DST ندارد؛
- ambiguous/nonexistent local time در zoneهای مربوط؛
- relative time و boundary «امروز/دیروز»؛
- calendar conversion، leap/boundary و round-trip طبق library/contract؛
- server job، notification و report cut-off مستقل از display؛
- tzdata/CLDR/library upgrade impact و regression.
Number، Currency و Unit را با CLDR و Business Contract ترکیب کنید
Locale data میتواند pattern، symbol و نام localized بدهد؛ اما مبلغ، Currency مجاز، scale، rounding، واحد تجاری و conversion را Product/Finance تعیین میکنند. Symbol `$` یا `ریال` بدون Currency code/context ممکن است ambiguous باشد.
- positive/negative/zero و sign placement؛
- grouping/decimal separator و non-breaking spaces؛
- Latin/Persian/Arabic-Indic digit systems طبق Contract؛
- Currency code/symbol/name و narrow symbol؛
- IRR canonical در برابر تومان نمایشی با conversion صریح؛
- large/small/rounding boundary و screen-reader output؛
- unit name plural/abbreviation و conversion precision؛
- copy/paste/parse/CSV/PDF consistency.
برای Journey مالی و Ecommerce، Money Contract و Ledger guide و راهنمای تست فروشگاه اینترنتی ownerهای محاسبه و Order lifecycle هستند. Locale formatting جای صحت مبلغ یا Price source را نمیگیرد.
Collation، Search و Case Folding را نسخهدار کنید
Sort و Search به زبان، strength، accent/diacritic، punctuation، digit، normalization و library/version وابستهاند. ترتیب Unicode code point معمولاً ترتیب انسانی مطلوب نیست. در عین حال «طبیعی» بودن ترتیب باید برای محصول و Dataset تعریف شود.
| ناحیه | Fixture | Oracle |
|---|---|---|
| Sort | حروف/اعداد/diacritics/mixed scripts | collator config/version + expected order |
| Search | ی/ی، ک/ک، نیمفاصله، normalization | query policy + relevance owner |
| Case-insensitive | locale-sensitive case mappings | library behavior per locale |
| Prefix | grapheme/combining sequences | user-visible boundary policy |
| Identifier | mixed/confusable scripts | security policy, not linguistic fuzziness |
| Index upgrade | new ICU/CLDR/collation version | reindex + golden query diff |
نام، آدرس و تلفن را قالب انگلیسی ندانید
همه افراد first/middle/last ثابت ندارند؛ همه Addressها State/ZIP یکسان ندارند و Phone display با E.۱۶۴ storage یکی نیست. Model و validation را بر بازارهای واقعی Scope طراحی کنید، اما داده تست را ساختگی و غیرقابل تماس نگه دارید.
- تکنام، چندبخشی، طولانی، apostrophe/hyphen/space و چند Script؛
- display order و salutation بدون حدس gender/title؛
- Address fieldهای optional/required per market؛
- multi-line، RTL/LTR mixed، postal code formats و label print؛
- Phone country code، national display، extension و non-mobile؛
- Normalization برای search/display جدا از authoritative original؛
- validation service unavailable و manual override با audit؛
- عدم استفاده از نام/نشانی/شماره واقعی در Test.
Input، Keyboard و IME را فراموش نکنید
Paste کردن Text با تایپ از IME یکسان نیست. Composition eventها، dead key، autocorrect، virtual keyboard، hardware layout، selection، cursor و validation-on-input میتوانند داده را خراب کنند یا کاربر را پیش از تکمیل composition رد کنند.
| Scenario | بررسی | Failure نمونه |
|---|---|---|
| IME composition | validation پس از composition boundary | کاراکتر نیمهساخته reject میشود |
| Paste | normalization/length/sanitize | grapheme قطع یا control پنهان |
| Mixed direction edit | cursor/select/backspace | حذف segment اشتباه |
| Mobile keyboard | input type/action/autofill | کیبورد نامناسب یا Enter بیاثر |
| Shortcut | physical layout مستقل | shortcut با letter locale خراب |
| Voice/dictation | اگر در Scope و platform | punctuation/locale mismatch |
| Max length | bytes/code units/graphemes contract | emoji یا combining mark نصف میشود |
Font، Shaping و Fallback را با متن واقعی بسنجید
وجود glyph در یک فونت به معنای خوانایی، shaping صحیح یا metric سازگار نیست. Fallback میتواند وزن/ارتفاع/spacing را عوض و layout را بشکند. Webfont failure، subset ناقص، variable axis، combining mark و emoji sequence را در platformهای واقعی تست کنید.
- coverage scripts و glyphهای لازم؛
- Arabic joining، combining marks و diacritics placement؛
- ligature و shaping engine/platform differences؛
- font fallback chain و mixed-font line metrics؛
- bold/italic/weight availability و synthetic style؛
- font load timeout، FOIT/FOUT و offline/cached behavior؛
- PDF/print/email embedding و licensing؛
- zoom/reflow و accessibility readability.
Layout Resilience را به درصد ثابت محدود نکنید
ادعای «ترجمه همیشه ۳۰٪ بلندتر است» قانون نیست؛ رشته کوتاه ممکن است چند برابر شود و رشته بلند کمتر تغییر کند. Component باید با range واقعی، pseudo expansion، longest approved translations، dynamic values، zoom و narrow viewport آزموده شود.
| Component | Stress input | Invariant |
|---|---|---|
| Button | long label + 200% zoom | text readable، action reachable |
| Tabs | many long labels | wrap/scroll/overflow policy usable |
| Table | RTL + long headers + numbers | association/alignment remains clear |
| Modal | long legal/validation content | focus/action not clipped |
| Toast/status | plural + identifiers | complete and announced as designed |
| Chart | localized axis/legend | data semantics and labels visible |
| Notification | platform truncation | critical meaning survives or opens safely |
| PDF/print | page break/font fallback | no lost fields/signatures/references |
Accessibility را با Language و Direction پیوند دهید
Screen reader و Browser برای pronunciation و processing به language metadata نیاز دارند. W3C توصیه میکند زبان پیشفرض HTML با `lang` روی عنصر `html` اعلام شود و بخشهای با زبان متفاوت نیز markup مناسب داشته باشند. `dir` برای direction مسئله جداست.
راهنمای W3C برای اعلام زبان در HTML استفاده از Language Tag و `lang` را توضیح میدهد. برای چکلیست کامل Keyboard، Focus، Name/Role/Value، Status message، Reflow و معیارهای WCAG ۲.۲ به راهنمای تست دسترسپذیری مراجعه کنید.
- `lang` page و nested foreign-language spans؛
- `dir` و isolation برای mixed content؛
- accessible name/description ترجمهشده و non-empty؛
- validation/status announcement در Locale صحیح؛
- keyboard order پس از RTL layout؛
- zoom/reflow با expansion و font metrics؛
- Alt/caption/transcript locale ownership؛
- Voice/speech output numbers, dates, abbreviations and code segments.
Translation Pipeline را Build Artifact کنید
Source code/content → extract messages + schema + context → validate keys/placeholders/markup → send versioned job to TMS → translate + review + terminology checks → import target resources → compile/validate bundles → pseudo + locale functional/visual tests → linguistic in-context review → signed locale release manifest → deploy/canary/monitor/fallback or rollback
TMS source of collaboration است، نه لزوماً source of truth برای Build. Release باید دقیقاً بگوید کدام resource snapshot، source hash، translation memory/glossary/style version و reviewer approvals وارد Artifact شدهاند.
| Stage Gate | Check | Failure behavior |
|---|---|---|
| Extract | dynamic/hardcoded/missing context | fail or reviewed exception |
| Schema | keys/placeholders/plurals/markup | fail build for critical mismatch |
| Translate | status, glossary, source-change freshness | hold/fallback per policy |
| Import | encoding/escaping/file syntax | reject bundle |
| Compile | runtime formatter compatibility | fail artifact |
| Visual | pseudo/approved targets/platforms | finding + severity/owner |
| Linguistic | in-context meaning/tone/terminology | review decision |
| Release | manifest/evidence/unknown/rollback | Go/Conditional/Hold |
Machine Translation و AI را ابزار، نه Sign-off، بدانید
Machine translation میتواند draft یا پیشنهاد بسازد؛ کیفیت آن به language pair، domain، prompt/context، glossary، model/version و text type وابسته است. گزاره «همیشه کافی نیست» یا «هرگز نباید استفاده شود» نیز بدون Context مطلق است. Risk و review depth را بر content class تنظیم کنید.
| Content class | Risk نمونه | Pipeline نمونه |
|---|---|---|
| Internal low-risk draft | برداشت نادرست محدود | MT + user disclosure/review as needed |
| General UI | task confusion/terminology drift | MT suggestion + linguistic/in-context review |
| Transactional | amount/state/action misunderstanding | domain review + functional evidence |
| Security/auth | unsafe action or secret exposure | security/content approval + exact placeholders |
| Legal/regulated | rights/obligation mismatch | qualified legal process per jurisdiction |
| Marketing/brand | tone/cultural/reputation | brand/local market review or transcreation |
- داده حساس، secret و unreleased content به ابزار نامجاز ارسال نشود.
- Model/provider/version و prompt/context در حد policy ثبت شوند.
- Glossary و do-not-translate terms enforce شوند.
- Hallucinated placeholder/markup/key با schema gate رد شود.
- Reviewer AI output را مستقل ارزیابی کند، نه فقط post-edit سطحی.
- MT provenance و disclosure بر اساس policy/market حفظ شود.
Linguistic QA را قابلردگیری کنید
«Native speaker گفت خوب است» Evidence کافی نیست. Native بودن هم expertise حوزه، مهارت QA یا نمایندگی همه کاربران را تضمین نمیکند. Reviewer باید نقش، Locale competence، domain context، guideline، conflict path و independence مناسب داشته باشد.
Linguistic Finding findingId / locale / build / resourceVersion screen/journey / key / source / target category: meaning / terminology / grammar / style / truncation / functional / legal... observation: what is present, without interpretation mixed in impact/context: actor and task reference: glossary/style/domain rule/version suggested correction: if authorized alternatives/uncertainty: dialect or product ambiguity severity/priority: defined scale, not personal preference owner/decision: accepted/fixed/rejected/deferred retest evidence: changed artifact and screenshot/log privacy: synthetic content only
Terminology و Style Guide را Testable کنید
Glossary فقط دو ستون word/translation نیست. Term باید concept، context، part of speech، approved/forbidden variants، capitalization، inflection، product names، owner و effective version داشته باشد. Style guide نیز tone، address، punctuation، digits، quotation، date/number choices و accessibility language را مشخص کند.
- exact forbidden term scan و false-positive exceptions؛
- concept-level review برای inflection و compounds؛
- do-not-translate Product/SKU/API names؛
- consistent action verbs در Button، Menu و Help؛
- approved formal/informal address و pronouns؛
- punctuation/space/numbering rules؛
- inclusive/plain-language guidance با owner؛
- version diff و impact روی translation memory.
Screenshot و Visual Regression را با احتیاط بهکار ببرید
Screenshot diff میتواند overflow، overlap و direction regression را بیابد، اما pixel difference برابر defect نیست. Font rasterization، animation، dynamic date، network image و platform تفاوت میسازند. همچنین screenshot معنای ترجمه، keyboard flow یا screen-reader output را نمیسنجد.
| کنترل | هدف | محدودیت |
|---|---|---|
| Pinned font/platform/viewport | کاهش noise | platform coverage محدود |
| Deterministic data/clock | ثبات dynamic text | real variability را مدل نمیکند |
| Region masks | حذف animation/ads | ممکن است defect را پنهان کند |
| Component baselines | triage کوچکتر | end-to-end context ندارد |
| OCR/text extraction | missing/truncation hints | OCR error/language support |
| Human review | semantic visual judgment | sample/subjectivity |
| Accessibility checks | non-visual interaction | جدا از pixels |
Functional Regression را Locale-aware اما کمتکرار طراحی کنید
اجرای تمام E2E tests روی تمام Localeها معمولاً پرهزینه و کماطلاع است؛ اجرای فقط Base locale نیز Locale-specific defects را جا میاندازد. Coverage را لایهای و بر Risk/Change بسازید.
| لایه | Coverage | نمونه |
|---|---|---|
| Static/schema | همه key/Localeها در هر Build | missing/extra/placeholder/plural/markup |
| Unit/property | formatters و message functions | numbers/dates/plurals/normalization |
| Pseudo | همه Components/critical routes | hardcoded/overflow/RTL |
| Representative locales | script/direction/format clusters | LTR Latin، RTL Arabic-script، CJK، complex shaping |
| Target locale smoke | هر Release Locale | selection/bundle/critical journeys |
| Linguistic sampling | changed/high-risk content | context/terminology/tone |
| Full journey | critical market/platform combinations | signup/pay/order/security/legal |
برای انتخاب Browser/OS/device/engine و گزارش unsupported/unknown از راهنمای Compatibility Matrix استفاده کنید. Representative locale جای target-locale linguistic review را نمیگیرد.
Locale Matrix را بر Dimension بسازید، نه پرچم کشور
Locale Coverage Dimensions Language family and grammar complexity Script and shaping engine Direction: LTR / RTL / mixed Text expansion/compactness Plural/ordinal categories Numbering system and separators Calendar/timezone/relative time Collation/case/search behavior Input method/keyboard/IME Font/glyph/fallback Market-specific business/legal content Platform/browser/device/rendering engine Traffic/revenue/risk/support data Change impact and prior defect history
پرچم برای Locale selector نیز اغلب مبهم است: یک زبان چند کشور دارد و یک کشور چند زبان. Label را با نام زبان در خود زبان و در صورت نیاز region/script روشن طراحی کنید؛ انتخاب UX و accessibility را با کاربران و ownerهای مربوط بررسی کنید.
Email، Push، SMS، PDF و Export را خارج از UI نگذارید
Localization defectهای جدی در Surfaceهایی رخ میدهند که Component library اصلی ندارند. Template engine، provider، client و printer هر کدام محدودیت دارند. Artifact و Locale باید از Event/recipient context بیاید، نه Locale اپراتور یا server.
| Surface | ریسک | Evidence |
|---|---|---|
| dir/lang/CSS/client/font/template variables | raw MIME + representative clients | |
| SMS | encoding/segment count/truncation/Bidi | local sink + segment calculation |
| Push | platform length/action/localized app name | device notification capture |
| font embedding/shaping/page break/copy | render + text extraction + print | |
| CSV | encoding/delimiter/decimal/formula injection | round-trip in supported consumers |
| Filename | normalization/path/device compatibility | download/upload/filesystem matrix |
| Log/support | localized error hinders correlation | stable error code + localized message |
API و Integration Contract باید Locale را صریح حمل کند
API بهتر است machine-readable code و canonical typed data بدهد؛ localized message برای display میتواند افزوده شود، اما client logic نباید متن ترجمهشده را parse کند. Locale، timezone و currency Context در boundaryهای لازم صریح و authenticated/authorized باشند.
- stable error code مستقل از localized message؛
- requested/resolved Locale در response/debug evidence؛
- Content-Language و language metadata طبق protocol Contract؛
- Accept-Language cache/Vary و fallback؛
- canonical number/date در payload، localized string فقط با contract؛
- Partner unsupported locale و mapping/version؛
- Event recipient Locale snapshot در زمان لازم؛
- retry پس از تغییر preference deterministic طبق policy.
برای Contract، component و end-to-end boundaries به راهنمای تست یکپارچهسازی مراجعه کنید. ترجمه response بدون error code پایدار، automation و support را شکننده میکند.
SEO چندزبانه را از UI Locale جدا کنید
صفحه localized وب به URL، canonical، alternate/hreflang policy، sitemap، indexability، lang، title/meta، structured data و internal links نیاز دارد. Client-side switch بدون URL مستقل ممکن است برای Crawl/Share/Analytics مبهم باشد. راهبرد دقیق به سایت و Search owner مربوط است.
| Check | Invariant | ادعای ممنوع |
|---|---|---|
| Locale URL | stable/shareable/return correct content | URL خاص رتبه را تضمین میکند |
| Canonical | طبق duplicate/variant strategy | همه Locales یک canonical واحد لازم دارند |
| hreflang/alternates | reciprocal/valid/supported mapping per strategy | traffic guaranteed |
| lang/dir | actual content metadata | Search market targeting کامل |
| Title/meta | localized, unique, non-fallback where required | CTR guaranteed |
| Structured data | content/value consistency | rich result guaranteed |
| Internal links | Locale route consistency/no loops | هر لینک باید ترجمه مستقل داشته باشد |
Security و Privacy: Unicode و Locale ورودی قابل اعتماد نیستند
Locale header، language tag، translated markup، filename و user content میتوانند malformed یا adversarial باشند. Confusable identifiers، Bidi controls، log spoofing، path traversal در resource key، unsafe HTML، translation injection و cache poisoning را Threat model کنید.
- supported-locale allowlist و safe parsing؛
- resource path با user input ساخته نشود یا canonical/allowlisted باشد؛
- translation markup allowlist و context-aware escaping؛
- placeholder type و sensitivity schema؛
- Bidi/control characters در identifiers/logs policy و visible diagnostics؛
- confusable/mixed-script detection فقط در Domain لازم و با false-positive review؛
- Cache key شامل Locale Context لازم؛
- TMS/vendor least privilege، export، retention و incident plan؛
- PII/secret در screenshot、MT prompt، linguistic ticket یا analytics حذف شود.
برای Threat model و validation از راهنمای تست امنیت و برای data flow، vendor، retention و legal applicability از راهنمای تست حریم خصوصی استفاده کنید. Localization بهخودیخود شمول قانونی نمیسازد یا رفع نمیکند.
Performance و Bundle Delivery را اندازه بگیرید
افزودن Locale میتواند bundle، font، format library، server render، cache cardinality و first interaction را تغییر دهد. همه Resourceها را eager load نکنید مگر design و budget چنین میخواهد. Locale-specific performance را با Artifact و network واقعی بسنجید.
| Metric | Slice | Correctness companion |
|---|---|---|
| bundle/font bytes | locale/platform/cache state | required glyph/resources present |
| load/parse/compile time | cold/warm | resolved bundle version |
| SSR/format latency | locale/message complexity | correct plural/date/number |
| cache hit | requested/resolved locale | no cross-locale content mix |
| layout shift | font and expansion | content readable/action stable |
| translation API dependency | if runtime use is authorized | timeout/fallback/privacy |
| PDF/report generation | script/font/page count | complete fields/text |
Production Monitoring را به Locale Resolution وصل کنید
Error rate کلی ممکن است با یک Locale خراب سبز بماند. Signalها را به requested/resolved Locale، bundle version، platform، journey و key/domain slice کنید؛ بااینحال Locale میتواند داده حساس یا cohort کوچک بسازد، پس privacy و حداقلسازی لازم است.
| Signal | Counter-signal | Action |
|---|---|---|
| missing key count | criticality/unique keys/users | bundle/feature hold or fallback owner |
| fallback rate | allowed vs forbidden domain | translation/import investigation |
| formatter exceptions | input type/library version | contract/data fix |
| locale switch failures | selection source/route/cache | negotiation trace |
| truncation/overflow reports | component/platform/font | visual reproduction |
| support tickets | terminology/journey/severity | linguistic/product triage |
| bundle skew | code/resource version mismatch | rollback/cache purge |
| conversion/task metric | technical/market confounders | hypothesis، نه اثبات localization cause |
Release Manifest و Gate بسازید
Locale Release Manifest code/build/image digest: ___ supported locale registry: ___ BCP 47/locale/fallback config: ___ source resource schema/hash: ___ target bundle hashes/status: ___ CLDR/ICU/tzdata/font versions: ___ glossary/style/content versions:___ platform/browser artifacts: ___ pseudo/static/schema results: ___ functional/visual/a11y results:___ linguistic/legal approvals: ___ known fallback/limitations: ___ monitoring/rollback owner: ___ evidence pack/checksum: ___
Locale Release Memo Scope and change impact: ___ Critical journeys/content: ___ Missing/extra/schema findings: ___ Fallback and bundle freshness: ___ Unicode/Bidi/format evidence: ___ Platform/visual evidence: ___ Linguistic/domain approvals: ___ Security/privacy/a11y refs: ___ Blocked/inconclusive/stale: ___ Open defects and user exposure:___ Rollback/feature flags: ___ Production monitors: ___ Recommendation: Go / Conditional / Hold Authorized decision and expiry:___
آزمایش بازتولیدپذیر: Smoke سبز، Locale Gate قرمز
Fixture `fictional-locale-release-v1` شامل پنج Source message ساختگی انگلیسی و Bundle فارسی عمدیِ ناقص است. `shipping.eta` وجود ندارد؛ `legacy.extra` اضافی است؛ پیام پرداخت Placeholder واحد پول را حذف کرده؛ پیام کد یک Placeholder نام اضافه دارد؛ دو رشته UI hardcoded هستند؛ و پنج Container ساختگی ظرفیت کوتاه دارند.
Naive smoke - برای هر Base key: target message یا fallback English را Render کن - فقط non-empty بودن خروجی را Assert کن Contract audit - missing/extra key - exact placeholder schema - requested vs resolved locale/fallback - hardcoded UI inventory - deterministic pseudo expansion vs container contract
| Gate | نتیجه | یافته |
|---|---|---|
| Naive render smoke | PASS؛ ۵/۵ non-empty | یک fallback انگلیسی پنهان ماند |
| Key audit | FAIL | ۱ missing: `shipping.eta`؛ ۱ extra: `legacy.extra` |
| Placeholder audit | FAIL | ۲ mismatch: missing `currency` و extra `name` |
| Hardcoded scan | FAIL | `Cancel` و `SKU: SKU-SYN-A` |
| Pseudo layout | FAIL | ۵/۵ container در مدل طولی overflow |
| Contract release gate | HOLD | تا triage/owner decision |
{
"fixture": "fictional-locale-release-v1",
"naiveSmoke": {
"rendered": 5,
"nonEmpty": 5,
"pass": true,
"fallbackUsed": 1
},
"contractAudit": {
"missingKeys": ["shipping.eta"],
"extraKeys": ["legacy.extra"],
"placeholderMismatches": ["checkout.pay", "auth.code"],
"fallbackUsed": ["shipping.eta"],
"hardcodedUiStrings": ["Cancel", "SKU: SKU-SYN-A"],
"pseudoOverflows": 5,
"releaseGate": "HOLD"
}
}
محدودیتها: این Script فقط String/Key mechanics را روی Fixture دستنویس و عمداً خراب میسنجد. ترجمه فارسی، grammar، plural، Bidi، font، screenshot، accessibility، Browser، device، TMS، API، عملکرد، فرهنگ یا بازار واقعی را بررسی نمیکند. Container length مدل pixel layout نیست؛ پنج Overflow نتیجه حدهای دلخواه Fixture است، نه benchmark یا درصد Expansion عمومی. HOLD الگوریتم انتشار عمومی نیست.
درس محدود: non-empty render باید با schema، provenance/fallback، hardcoded inventory و visual/pseudo evidence تکمیل شود. Audit static نیز جای Linguistic و functional review را نمیگیرد.
سناریوی بومی: انتشار فارسی آفلاین و ساختگی
یک اپ آزمایشی با Localeهای `en` و `fa-IR`، داده `SYN-*` و Clock ثابت بسازید. هیچ نام، شماره، Email، Address، Payment، OTP، Token، حساب یا سرویس ترجمه واقعی در آن نیست. Bundleها و Fontها محلیاند و Egress محیط بسته است. این Lab درباره بازار، قانون یا ترجیح همه کاربران ایران ادعایی ندارد.
| ریسک | تزریق ساختگی | Invariant | Evidence |
|---|---|---|---|
| Bundle completeness | یک key فارسی حذف | fallback forbidden key Gate را Hold کند | schema/telemetry |
| Placeholder | `{currency}` حذف | compile/import reject | contract audit |
| Unicode | ی/ی، ک/ک، combining، emoji | policy-specific normalize/preserve | round-trip/query |
| Bidi | فارسی + `ORD-SYN-۴۲` + `۱۲۰۰۰۰ IRR` | isolation، logical copy | render/edit/copy |
| Digits | ۰۱۲/۰۱۲/۰۱۲ | display/input per contract | format/parse |
| Time | UTC، Asia/Tehran، شمسی display | instant unchanged; view correct | API/UI/export |
| RTL layout | pseudo RTL + long strings | semantic components usable | screenshots/tasks |
| No egress | Email/PDF/MT request | local sink/fail closed | network policy |
نقشها و Decision Rights
| نقش | مسئولیت نمونه | نباید بهتنهایی ادعا کند |
|---|---|---|
| i18n Engineering | resource/runtime/format/Bidi architecture | کیفیت زبانی یا market fit |
| Localization manager | pipeline/vendor/schedule/status | functional correctness |
| Translator/Linguistic reviewer | meaning/grammar/terminology/tone | امنیت، قانون یا همه کاربران |
| Product/Domain/Legal | content intent/rule/approval/applicability | implementation behavior بدون evidence |
| Design/UX/A11y | layout/component/task/accessibility | grammar یا business correctness |
| QA/Test | contracts، scenarios، evidence/limitations | تضمین بازار/اعتماد/درآمد |
| Security/Privacy | Unicode/TMS/data/vendor threat controls | Localization quality کامل |
| Release/Risk owner | residual risk، deploy/rollback decision | پنهانکردن Unknown/fallback |
برنامه ۳۰روزه Pilot
| هفته | خروجی | کار | معیار اتمام |
|---|---|---|---|
| ۱: Contract | Locale registry/contract/fallback | دو Locale، یک Journey، owners، versions | selection/formats/fallback روشناند |
| ۲: Pipeline | resource schema و pseudo build | extract، keys، placeholders، plural، hardcoded | static gates reproducibleاند |
| ۳: Evidence | locale matrix test pack | Unicode/Bidi/format/input/visual/linguistic | findings به key/build trace میشوند |
| ۴: Release | manifest، memo و monitors | canary/fallback/rollback و Unknown review | owner/decision/expiry ثبت شدهاند |
- یک Journey حساس و دو Locale متفاوت انتخاب کنید.
- Locale Contract و exact fallback chain بنویسید.
- همه Source/Target keyها و Placeholderها را Gate کنید.
- Accented، expansion و RTL pseudo build بسازید.
- Critical formats و mixed-direction identifiers را اجرا کنید.
- Reviewer زبانی را با screenshot/context و glossary مجهز کنید.
- requested/resolved Locale و fallback را در Canary monitor کنید.
ضدالگوهای رایج تست Localization
| ضدالگو | مشکل | اصلاح |
|---|---|---|
| i18n یکبار انجام میشود | feature/library regression نادیده | continuous gates/change impact |
| l10n فقط ترجمه است | format/input/assets/rules جا میماند | Locale contract |
| Locale=Country | language/script/timezone/currency حدس | independent explicit dimensions |
| TMS=Production bundle | version/skew پنهان | signed release manifest |
| Non-empty=translated | fallback English سبز | requested/resolved source assertion |
| String concatenation | grammar/order/Bidi محدود | whole structured message |
| `count != 1` plural | Locale rules غلط | CLDR-pinned categories |
| همه متنها ۳۰٪ بلندتر | range واقعی جا میماند | pseudo + real longest strings |
| Mirror everything | icon/chart/media semantics میشکند | component mirroring matrix |
| UTF-8 solves Unicode | normalization/grapheme/Bidi نادیده | domain-specific Unicode tests |
| NFKC everywhere | semantic distinctions حذف | normalization contract |
| Native speaker=complete QA | domain/test/representation gaps | defined reviewer role/protocol |
| MT forbidden or sufficient universally | risk/context حذف | content-class pipeline |
| Screenshot diff=quality | meaning/a11y/function غایب | mixed evidence |
| All E2E × all Locales | cost/noise بالا | layered risk matrix |
| Production data in TMS/tickets | privacy/secret leak | synthetic/minimized context |
| Base locale gate only | target bundle defects | per-locale manifest/smoke/review |
| Fallback hides incident | mixed/unsafe content silent | domain policy/telemetry/owner |
چکلیست نهایی تست i18n و l10n
- i18n، l10n، translation، transcreation و linguistic QA مرز روشن دارند.
- Language، script، region، Locale، timezone، currency و market یکی فرض نشدهاند.
- Language Tagها BCP ۴۷ و Locale ID داخلی نسخهدارند.
- Locale selection precedence، persistence، cache و user choice تعریف شدهاند.
- Fallback chain per-domain، observable و ownerدار است.
- Resource key/source/context/owner/hash/status lifecycle دارد.
- Missing/extra/duplicate/deprecated/hardcoded keyها Gate میشوند.
- Placeholder name/type/count/markup/sensitivity schema دارد.
- String concatenation حساس حذف و structured message استفاده شده است.
- Plural/ordinal/select با CLDR/library version و boundary values آزمودهاند.
- Pseudo modes accented/expansion/RTL/missing-resource اجرا شدهاند.
- Encoding round-trip، grapheme، truncation، emoji و export بررسی شدهاند.
- Normalization policy per identifier/search/display/signature روشن است.
- Bidi mixed content، isolation، copy/edit و control chars آزمودهاند.
- Mirroring component-level است و icon/chart/media context دارد.
- Number/money/date/timezone/calendar/unit format و parse جدا از storageاند.
- Collation/search/case/index version و golden query evidence دارند.
- Name/address/phone models بازارمحور و data ساختگیاند.
- IME، paste، keyboard، cursor و length boundary آزمودهاند.
- Font coverage/shaping/fallback/load/PDF و platform differences بررسی شدهاند.
- Layout با pseudo، longest targets، zoom و narrow viewport resilient است.
- `lang`/`dir`، accessible names/statuses و screen-reader paths صحیحاند.
- Translation pipeline source→TMS→bundle→artifact قابل trace است.
- MT/AI بر اساس content risk، privacy و independent review کنترل میشود.
- Linguistic findings به key/build/reference/decision/retest وصلاند.
- Glossary/style guide concept، owner و version دارند.
- Visual regression deterministic است و محدودیت pixels را میپذیرد.
- Locale coverage لایهای و مبتنی بر script/direction/format/risk است.
- Email/SMS/Push/PDF/CSV/filename در Scope آزمودهاند.
- API code/canonical data را از localized message جدا کرده است.
- SEO URL/canonical/alternates/lang/meta/internal links policy دارد.
- Unicode/TMS/resource/markup/cache Threatها و Privacy کنترل شدهاند.
- Bundle/font/cache/render performance per-locale سنجیده شده است.
- Production missing/fallback/formatter/bundle-skew signals دارد.
- Release manifest Code/Resource/CLDR/ICU/tzdata/font/content را pin میکند.
- Blocked/Inconclusive/Stale/Unreviewed بهعنوان Unknown در Gate میآیند.
سؤالات متداول تست i18n و l10n
تفاوت تست i18n و l10n چیست؟
تست i18n قابلیت مهندسی مشترک—resource، Unicode، format، direction و layout—را برای پشتیبانی از چند Locale میسنجد. تست l10n Artifact و تجربه یک Locale/Market مشخص را از نظر bundle، محتوا، formats، assets، functional behavior و review بررسی میکند. هر دو با تغییر محصول تکرار میشوند و یکی جای دیگری نیست.
آیا `fa-IR` یعنی باید تومان، تقویم شمسی و Asia/Tehran استفاده شود؟
نه بهصورت خودکار. `fa-IR` Language Tag فارسی با Region ایران است، اما Currency، display unit، calendar، timezone و market rule ابعاد مستقل محصولاند. Locale Contract باید default، انتخاب کاربر، storage canonical و display policy هر کدام را مشخص کند.
Pseudo-localization چه چیزی را پیدا نمیکند؟
معنا، grammar، tone، terminology، cultural fit و قانون Locale واقعی را نمیسنجد؛ حتی RTL pseudo نیز زبان RTL واقعی یا همه platformها را مدل نمیکند. برای hardcoded text، expansion، encoding، layout و direction signal سریع میدهد و باید با target-locale functional/visual/linguistic evidence ترکیب شود.
آیا Machine Translation برای Localization کافی است؟
به content class، language pair، domain، risk و review بستگی دارد. MT میتواند draft مفید باشد، اما schema، placeholder، terminology، privacy و in-context review همچنان لازماند. متن Transactional، Security، Legal یا برند معمولاً فرایند تخصصیتر میخواهد؛ تصمیم مطلق برای همه محتوا درست نیست.
برای شروع کدام Localeها را تست کنیم؟
Localeهای واقعی بازار را با Risk و Change پوشش دهید و برای لایه فنی، نماینده Dimensionهای متفاوت مانند LTR/RTL، script/shaping، plural، formats، input و expansion انتخاب کنید. Representative locale جای review زبان مقصد را نمیگیرد. برای Pilot، Base، یک RTL مثل فارسی و یک Locale ساختاری متفاوت کافی است اگر Scope محدود باشد.
جمعبندی: Locale یک Release Artifact است
تست جهانیسازی و بومیسازی با بازکردن صفحه ترجمهشده تمام نمیشود. Locale Contract انتخاب و fallback را روشن میکند؛ resource schema از Key و Placeholder محافظت میکند؛ CLDR/Unicode/BCP ۴۷ داده و الگوریتمهای استاندارد را فراهم میکنند؛ pseudo و static gates خطا را زود مییابند؛ target-locale testing و linguistic review معنا و Context را میسنجند؛ و Release Manifest نسخه Code، Bundle، Library، Font و Content را به Evidence متصل میکند.
پرسش مفید «آیا ترجمه ۱۰۰٪ است؟» نیست. بپرسید: برای کدام Locale و Build، چه Bundle و Fallbackی resolve شد؟ Placeholder و plural schema سالماند؟ عدد، تاریخ و Bidi چه Contractی دارند؟ چه Surface و platformی اجرا نشده، چه Reviewerی محتوا را دیده و کدام Unknown با چه Ownerی باقی مانده است؟
روش تدوین و منابع
این راهنما با بازبینی انتقادی نسخه قبلی، حذف وعدههای بازار/درآمد/وفاداری/اعتماد/کاهش قطعی هزینه و جداسازی intent از صفحه فارسی/RTL تدوین شد. آزمایش با Node.js ۲۴.۱۸.۰، بدون dependency، deterministic و با Messageهای کاملاً ساختگی اجرا شد.
- RFC ۵۶۴۶ / BCP ۴۷: Language Tagها.
- Unicode UAX #۱۵: Normalization Forms و Conformance tests.
- Unicode UAX #9: Bidirectional Algorithm.
- Unicode CLDR Plural Rules و LDML/Locale data؛ نسخه library/data باید pin شود.
- W3C Internationalization: Language declaration و Bidi markup/controls.
بازبینی محتوایی: مرداد ۱۴۰۵. Unicode، CLDR، tzdata، Browser/platform، Font، Language guidance، TMS/MT و قانون تغییر میکنند؛ نسخه و Applicability محصول را پیش از Release تأیید کنید.

