اختبار التوطين والتدويل

اختبار التوطين (Localization testing) يتحقق من أن المنتج يعمل ويُقرأ صحيحاً ويبدو سليماً لمستخدمي إعداد محلي (Locale) بعينه — أي لغة مع منطقة، مثل العربية في السعودية (ar-SA) أو الهندية في الهند (hi-IN). وهو يشمل النص المترجَم، لكن معظم عيوبه ليست أخطاء ترجمة: بل تواريخ بالتقويم الخطأ، ومبالغ بفواصل خاطئة، وجمل مقطوعة من منتصفها، وتخطيطات تنكسر حين يتغير طول النص أو اتجاهه، وحروف تتحول إلى علامات استفهام في مكان ما بين النموذج وقاعدة البيانات.

هذا الدليل هو مدخل هذا المجال. يفرّق بين التدويل والتوطين والعولمة، ويرسم خريطة المجالات التي يجب على المختبِر تغطيتها، ويقدم فحوصاً وبيانات وأمثلة عيوب ملموسة للعربية والهندية والإنجليزية — وهي اللغات الثلاث التي تعمل بها أدوات متقن نفسها. أما التخطيط من اليمين إلى اليسار والنص ثنائي الاتجاه فلهما دليل خاص هو اختبار الواجهات العربية من اليمين إلى اليسار؛ وهذه الصفحة تلخصهما وتتعمق في كل ما سواهما.

التدويل والتوطين والعولمة: ما الذي نختبره؟

التدويل (Internationalization أو i18n) خاصية هندسية: يُبنى المنتج بحيث يمكن تكييفه مع أي إعداد محلي دون تغيير الكود. تعيش النصوص في ملفات موارد لا في القوالب؛ وتمر التواريخ والأرقام والعملات عبر واجهات تنسيق واعية بالإعداد المحلي؛ ولا يُفترض اتجاه ثابت للنص؛ ويكون التخزين والنقل باليونيكود من طرف إلى طرف. أما التوطين (Localization أو l10n) فهو التكييف لإعداد محلي واحد: النصوص المترجمة، والصيغ المحلية، والمحتوى المحلي، والنصوص القانونية، ووسائل الدفع، وصيغ العناوين والهواتف. والعولمة (Globalization أو g11n) مصطلح جامع للجهد التجاري والهندسي الذي يضم الاثنين ليُقدَّم منتج واحد في أسواق كثيرة.

التفريق مهم لأن العيوب مختلفة. عيب التدويل يعيش في الكود ويظهر في كل الإعدادات المحلية — رمز عملة مكتوب في الكود، أو جملة مركّبة بالدمج، أو تاريخ يُحلَّل بنمط ثابت. وعيب التوطين يعيش في محتوى إعداد محلي واحد — مصطلح خاطئ، أو ترجمة ناقصة، أو صيغة عنوان خاطئة. وعيوب التدويل أرخص ما تكون حين تُكتشف قبل وجود أي ترجمة، بالتوطين الزائف؛ أما عيوب التوطين فتحتاج إلى الترجمة الحقيقية، وتحتاج جودة اللغة فيها إلى متحدث أصلي.

  • الإعداد المحلي (Locale) — يُعرَّف بوسم لغة BCP 47 (المعيار RFC 5646): ar وar-SA وhi-IN وen-IN. الجزء الخاص باللغة يختار الترجمة، وجزء المنطقة يختار الصيغ والعملة والتقويم الافتراضي.
  • اختبار التدويل — هل يستطيع المنتج دعم الإعدادات المحلية أصلاً؟ شغّله بنص موطّن توطيناً زائفاً، وبيانات يونيكود، واتجاه من اليمين إلى اليسار، وصيغ غير افتراضية.
  • اختبار التوطين — هل هذا الإعداد المحلي بعينه صحيح؟ الترجمة في سياقها، والصيغ، والملاءمة الثقافية، والتخطيط بالنصوص الحقيقية.

خريطة اختبار التوطين

يمتد اختبار التوطين عبر مجالات تحتاج إلى مهارات وبيانات مختلفة. استخدم هذه الخريطة لتخطيط التغطية لكل إعداد محلي؛ والأقسام التالية تمر على كل مجال، أما التخطيط من اليمين إلى اليسار فيغطيه دليل اختبار RTL بالتفصيل.

  • جودة اللغة والترجمة — المصطلحات، والسياق، والاكتمال، وصيغ الجمع والتذكير والتأنيث، ومعاملات الرسائل، والاقتطاع.
  • الصيغ المحلية — التواريخ والتقاويم (الميلادي والهجري)، والأوقات والمناطق الزمنية، والأعداد والأرقام، والعملات، ووحدات القياس، والعناوين، وأرقام الهواتف، والأسماء الشخصية.
  • معالجة النص وأنظمة الكتابة — الترميز، وتطبيع اليونيكود، والعناقيد الرسومية، والخطوط، والفرز، والبحث، وطرق الإدخال.
  • التخطيط — تمدد النص وانكماشه، وارتفاع السطر لأنظمة الكتابة التي لها علامات فوق السطر وتحته، وفي العربية مجال عكس الواجهة والنص ثنائي الاتجاه بأكمله.
  • اختيار الإعداد المحلي والرجوع الاحتياطي — كيف يختار المنتج الإعداد المحلي (إعداد المستخدم، أو ترويسة Accept-Language، أو الجهاز، أو الرابط)، وما الذي يحدث مع إعداد غير مدعوم، وهل ينتقل الاختيار إلى البريد الإلكتروني وملفات PDF والرسائل النصية والإشعارات.
  • إمكانية الوصول لكل إعداد محلي — سمة lang التي تخبر قارئ الشاشة بالصوت وقواعد النطق المناسبة، والأسماء الوصفية المترجمة للأيقونات وعناصر التحكم.

جودة اللغة والترجمة

يعمل المترجمون عادةً من جدول بيانات أو نظام لإدارة الترجمة دون أن يروا الشاشة، ومن هنا يأتي كثير من عيوب الترجمة. فكلمة "Save" الإنجليزية قد تكون فعلاً (احفظ الملف) أو اسماً (توفير في خصم)؛ و"Open" قد تكون حالة (مفتوح) أو أمراً (افتح)؛ والمترجم بلا سياق يختار واحداً. ومهمة المختبِر أن يراجع كل نص على الشاشة الحقيقية، وأن يذكر مفتاح النص مع لقطة الشاشة حتى يقع الإصلاح في المورد الصحيح.

صيغ الجمع هي أشيع العيوب البنيوية. للإنجليزية صيغتا جمع عدديتان. أما قواعد الجمع في مستودع CLDR من يونيكود فتمنح العربية ست فئات — zero (0)، وone (1)، وtwo (2)، وfew (الأعداد التي آخر رقمين فيها من 3 إلى 10، مثل 3 أو 103)، وmany (آخر رقمين من 11 إلى 99)، وother (مثل 100 إلى 102) — وتمنح الهندية فئتين، تُستخدم فيهما صيغة "one" للعددين 0 و1. والكود الذي يختار الصيغة بالشرط count === 1 خاطئ للعربية من أساسه. والإصلاح صيغة رسائل تدعم فئات الجمع؛ والاختبار جدول أعداد يصيب كل فئة.

  • اتساق المصطلحات — مصطلح واحد لكل مفهوم عبر الشاشات وصفحات المساعدة والبريد، يُراجع مقابل المسرد. تسمية السلة "سلة" في شاشة و"عربة" في أخرى عيب.
  • النصوص غير المترجمة — إنجليزية متروكة داخل الواجهة العربية أو الهندية؛ وتكثر في رسائل التحقق وأخطاء API والبريد والنصوص المضافة في آخر السبرنت.
  • النصوص المدموجة (Concatenated strings) — الجمل المركّبة من أجزاء ("You have" + n + "items") لا يمكن ترجمتها صحيحاً لأن ترتيب الكلمات والمطابقة يختلفان؛ ويجب أن تكون كل جملة رسالة واحدة بمعاملات.
  • معاملات الرسائل — يجب أن تبقى {name} أو %s داخل الترجمة كما هي؛ فالمعامل المترجَم أو المحذوف يُظهر أقواساً خاماً أو يُسقط أداة التنسيق.
  • التذكير والتأنيث وأسلوب الخطاب — الأفعال والصفات العربية تطابق الجنس؛ قرر كيف تخاطب الرسائل المستخدم وتحقق من تطبيق القرار باتساق.
# 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)
للعربية ست فئات جمع، وتعود few عند 103، لذا لا يصيب الشرط count === 1 من أعداد الاختبار إلا 1 و100 إلى 102.

العربية (ar): فئة CLDR

المحور من 0 إلى 110
  • 0zero
  • 1one
  • 2two
  • 3–10few
  • 11–99many
  • 100–102other
  • 103–110few

الشرط count === 1: صيغة one، وإلا other

  • 0خطأ، والصحيح zeroفشل
  • 1صحيحنجاح
  • 2–99خطأ، والصحيح two أو few أو manyفشل
  • 100–102صحيحنجاح
  • 103–110خطأ، والصحيح fewفشل

الهندية (hi): فئة CLDR

المحور من 0 إلى 5
  • 0, 1one
  • 1.5, 2, 5 …other

المسافات على المحور ليست بمقياس ثابت: لكل عدد اختبار من المثال، وللعدد 110 حيث تنتهي few، موضعه. ويُقرأ الشرط ككود على الطريقة الإنجليزية: صيغة one للعدد 1، وصيغة other لكل عدد آخر. وفي الهندية يخطئ عند 0.

التوطين الزائف: اكتشف عيوب التدويل قبل الترجمة

التوطين الزائف (Pseudo-localization) يستبدل كل نص في الواجهة بنسخة محوّلة آلياً ما زال الفريق يستطيع قراءتها: حروف بعلامات، وطول إضافي، وأقواس تحدد بداية كل رسالة ونهايتها. شغّل المنتج بالإعداد الزائف فتظهر دفعة واحدة كل فئات العيوب التي لا تحتاج إلى ترجمة حقيقية — النص المكتوب في الكود يبقى إنجليزياً عادياً، والجملة المدموجة تظهر قطعاً متعددة بين أقواس، والاقتطاع يقطع القوس الختامي، والمحارف خارج ASCII تكشف مشكلات الترميز.

يوفر Android إعدادين زائفين يمكن تفعيلهما في بنيات التصحيح: English (XA) الذي يضيف العلامات ويمدد النص ويحيط كل رسالة بأقواس، وAR (XB) الذي يحوّل الاتجاه إلى اليمين-إلى-اليسار ويعكس ترتيب المحارف، فيستطيع الفريق اكتشاف مشكلات العكس والنص ثنائي الاتجاه دون أن يعرف لغة تُكتب من اليمين. وعلى الويب يكون الإعداد الزائف عادةً ملف موارد إضافياً يُولَّد أثناء البناء من النصوص المصدرية.

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

التواريخ والتقاويم والمناطق الزمنية

صيغة التاريخ أكثر من ترتيب اليوم والشهر. فالإعداد المحلي يحدد التقويم، وأسماء الأشهر، والأرقام، والفواصل، وأول أيام الأسبوع، ونظام الساعة 12 أو 24. وفي السعودية تقويمان مستخدمان يومياً: التقويم الميلادي، والتقويم الهجري الذي توحّد المملكة حسابه بتقويم أم القرى. وكثير من المنتجات يعرض الاثنين أو يترك الاختيار للمستخدم؛ وكل موضع يعرض تاريخاً أو يقبله أو يخزنه أو يقارنه يجب أن يكون واضحاً في أي تقويم يستخدم.

لا تفترض ما ينتجه "ar-SA". فالقيم الافتراضية للإعداد المحلي تأتي من بيانات CLDR داخل بيئة التشغيل وتتغير بين الإصدارات: كانت بيئات التشغيل الأقدم تنسّق تواريخ ar-SA بالتقويم الهجري افتراضياً، بينما تستخدم الحديثة التقويم الميلادي بالأرقام العربية المشرقية. اطلب التقويم ونظام الأرقام صراحةً — مثلاً بامتدادات اليونيكود ar-SA-u-ca-islamic-umalqura أو ar-SA-u-nu-latn — واختبر النتيجة على كل بيئة تشغيل تطلقها: الخادم والمتصفحات والجوال. وقد تضع طرق الحساب الهجري المختلفة (أم القرى، والجدولي المدني) اليوم نفسه في تواريخ مختلفة، لذا يجب أن يسمّي اختبار التحويل التقويم بعينه لا أن يكتفي بكلمة "هجري".

تأتي المناطق الزمنية من قاعدة بيانات IANA tz. المنطقة Asia/Riyadh هي UTC+03:00 والسعودية لا تطبق التوقيت الصيفي؛ والمنطقة Asia/Kolkata هي UTC+05:30 دون توقيت صيفي أيضاً. وهذا يجعل عيوب التوقيت الصيفي (DST) غير مرئية في الاختبار المحلي وحقيقية لمستخدمين في أوروبا أو أمريكا الشمالية. خزّن اللحظات الزمنية بتوقيت UTC أو بفارق صريح (ISO 8601)، وحوّلها إلى منطقة المستخدم للعرض فقط، واختبر فارق نصف ساعة، ومنطقة تطبق التوقيت الصيفي، وأوقاتاً قريبة من منتصف الليل حيث يتغير اليوم.

  • كل حقل تاريخ يعلن تقويمه؛ واختيار تاريخ في منتقي التاريخ الهجري يخزن القيمة نفسها التي يخزنها اختيار التاريخ الميلادي المقابل.
  • نهايات الأشهر والسنوات: أشهر أم القرى 29 أو 30 يوماً؛ اختبر آخر يوم في الشهر وفي السنة في التقويمين.
  • انزياح منتصف الليل: الطلب المسجَّل الساعة 01:30 بتوقيت الرياض يقع في اليوم السابق بتوقيت UTC؛ والتقرير المجمَّع حسب يوم UTC يعرضه في تاريخ خاطئ.
  • الأسبوع وعطلته: أول أيام الأسبوع يختلف حسب الإعداد المحلي، والعطلة الأسبوعية في السعودية الجمعة والسبت؛ ويجب أن تتبع التقاويم والجداول وحساب أيام العمل قاعدة المنتج لا قاعدة مكتوبة في الكود.
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

جرّبها: مولّد بيانات اختبار التواريخ جرّبها: محوّل المناطق الزمنية جرّبها: محوّل الطوابع الزمنية جرّبها: محوّل ISO 8601

الأعداد والأرقام والعملات

يمكن أن يستخدم النص العربي الأرقام الغربية (⁦0–9⁩) أو الأرقام العربية المشرقية (٠١٢٣٤٥٦٧٨٩)، ومع الأرقام المشرقية تتغير الفواصل أيضاً: الفاصلة العشرية العربية ٫ (U+066B) وفاصل الآلاف العربي ٬ (U+066C). ويستخدم النص الهندي عادةً الأرقام الغربية، مع أن أرقام الديفاناغاري (०–९) موجودة ويمكن طلبها. وتجمّع الهند الأعداد الكبيرة بطريقة مختلفة — 12,34,567 وفق نظام اللاك (1,00,000) والكرور (1,00,00,000) — في en-IN وhi-IN كليهما. قرر لكل إعداد محلي أي أرقام وأي تجميع يستخدم المنتج، ثم اختبر العرض والإدخال: فقد يكتب المستخدم أرقاماً مشرقية في حقل مبلغ أو هاتف، وعلى المنتج إما قبولها وتوحيدها أو رفضها برسالة واضحة.

تُعرَّف العملات برموز ISO 4217 — SAR للريال السعودي وINR للروبية الهندية، ولكل منهما خانتان عشريتان للوحدة الفرعية. نسّق المبالغ بالإعداد المحلي لا بقوالب نصية: فالرمز وموضعه والمسافة تختلف حسب الإعداد المحلي. وقد أطلق البنك المركزي السعودي رمزاً خاصاً بالريال في 2025، ويرمّزه الإصدار 17.0 من يونيكود بالنقطة U+20C1 SAUDI RIYAL SIGN؛ فإن استخدمه تصميمك فتحقق من الخطوط التي تستطيع عرضه على أجهزتك المستهدفة، لأن الخط الذي لا يحوي الرسم يعرض مربعاً فارغاً.

تحتوي النصوص المنسّقة محلياً على محارف غير مرئية. فتنسيق مبلغ بالريال للإعداد ar-SA ينتج علامة من اليمين إلى اليسار (U+200F) في الطرفين ومسافة غير فاصلة قبل العملة، فيفشل الاختبار الذي يقارن بنص مكتوب يدوياً مع أن الشاشة تبدو صحيحة. قارن بمخرجات واجهة التنسيق نفسها، أو أزل المحارف غير المرئية في التحقق عن قصد.

  • التحليل: "1.234" تعني ألفاً ومئتين وأربعة وثلاثين في بعض الإعدادات المحلية وواحداً فاصلة اثنين ثلاثة أربعة في غيرها؛ والقيمة المنسّقة للعرض يجب أن تُحلَّل بالإعداد المحلي نفسه.
  • أرقام الهواتف وأرقام IBAN وأرقام الهوية معرّفات لا كميات: لا تجمّعها ولا تحوّل أرقامها عند العرض.
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):  १२,३४,५६७

جرّبها: مولّد بيانات الاختبار العربية جرّبها: مولّد بيانات الاختبار الهندية جرّبها: مولّد مجموعات الأرقام العشرية

النص واليونيكود وأنظمة الكتابة

يجب أن تتفق كل طبقة على UTF-8: ترميز meta في HTML وترويسة Content-Type في HTTP، وإرسال النماذج، وAPI، وطوابير الرسائل، وأعمدة قاعدة البيانات واتصالاتها، والسجلات، وتصدير CSV أو PDF. وحين تقرأ طبقة ما بايتات UTF-8 بترميز قديم أحادي البايت تكون النتيجة نصاً مشوّهاً (Mojibake) — فتتحول "مرحبا" إلى شيء مثل "مرحبا" — وقد تجعل رحلة ذهاب وعودة التلف دائماً. علامات الاستفهام مكان الحروف تعني عادةً أن المحارف ضاعت في تحويل؛ والمربعات الفارغة تعني عادةً أن الخط لا يحوي الرسم. وفي MySQL تخزن مجموعة المحارف القديمة utf8 (أي utf8mb3) العربية والديفاناغاري لكنها لا تخزن المحارف التكميلية رباعية البايت، ومنها معظم الرموز التعبيرية؛ أما utf8mb4 فتخزن اليونيكود كله.

قد يُخزَّن النص المرئي نفسه بتسلسلات مختلفة من نقاط الترميز — "é" نقطة واحدة مركّبة مسبقاً أو "e" مع علامة مركِّبة. ويجعلها تطبيع اليونيكود (NFC وNFD وNFKC وNFKD) قابلة للمقارنة، لذا يجب أن يطبّع البحث وفحوص التفرد وأسماء المستخدمين باتساق. والطول ملتبس أيضاً: الكلمة الهندية "नमस्ते" هي 6 نقاط ترميز، و6 وحدات UTF-16، و18 بايت UTF-8، و3 محارف يدركها المستخدم (عناقيد رسومية: न، म، स्ते). والحد المحسوب بالبايتات، والحد المحسوب بالمحارف، والمؤشر الذي يتحرك بنقطة ترميز — كلها ستختلف.

تجمع الديفاناغاري الحروف الساكنة في حروف مركّبة (क्ष، स्त) عبر علامة الفيراما، وبعض علامات الحركات تُرسم قبل الحرف الذي تليه في الذاكرة — فعلامة i في "कि" تُخزَّن بعد क لكنها تظهر على يساره. والاقتطاع أو التظليل أو تحريك المؤشر داخل العنقود يترك علامة حركة بلا قاعدة، وتعرضها محركات العرض عادةً مع دائرة منقطة (◌ि). والخط الذي لا يدعم تشكيل الديفاناغاري كاملاً يعرض الحروف المركّبة حروفاً منفصلة بفيراما ظاهرة.

الفرز والبحث يختلفان حسب الإعداد المحلي: استخدم الترتيب الذي توفره المنصة (Intl.Collator في JavaScript، وترتيبات المقارنة في قاعدة البيانات) واختبر بأسماء تبدأ بصور الألف المختلفة (ا أ إ آ)، مع التشكيل ودونه، وبأنظمة كتابة مختلطة. وللإدخال فحوصه أيضاً: لوحات المفاتيح العربية، والهندية المكتوبة بتخطيط InScript أو بلوحة نقل صوتي، ومحررات أساليب الإدخال (IME) التي تركّب النص عبر عدة ضغطات — فالتحقق الذي يعمل مع كل ضغطة قد يقاطع عملية التركيب.

  • تمدد النص وانكماشه: قد تكون الترجمة أطول كثيراً أو أقصر من الإنجليزية، خاصة في التسميات القصيرة؛ اختبر الأزرار والتبويبات وعناوين الجداول والتنبيهات المنبثقة والشارات بالنصوص الحقيقية لكل إعداد محلي.
  • المساحة الرأسية: للديفاناغاري علامات حركات فوق الخط العلوي وتحته، وللعربية تشكيل فوق الحروف وتحتها؛ وارتفاعات الأسطر الثابتة مع إخفاء الفائض تقصّها.
  • الرسائل النصية: الرسالة التي تحتوي عربية أو ديفاناغاري تُرسل عادةً بترميز UCS-2 بمعدل 16 بتاً للمحرف؛ ولأن بيانات المستخدم في الرسالة الواحدة 140 ثُمانية (3GPP TS 23.040)، تتسع الرسالة الواحدة عندئذٍ لـ 70 محرفاً بدلاً من 160 في أبجدية GSM ذات السبعة بتات، لذا قد تنقسم قوالب رموز التحقق (OTP) والإشعارات إلى عدة رسائل.

جرّبها: مولّد مجموعات بيانات Unicode جرّبها: عدّاد طول السلاسل النصية جرّبها: عدّاد الأحرف جرّبها: مولّد مجموعات الأحرف الخاصة

كيف تنفّذ اختبار التوطين

ينجح اختبار التوطين أكثر حين يكون سلسلة من البوابات لا جولة واحدة في النهاية: فأرخص العيوب (عيوب التدويل) تُكتشف قبل الترجمة، وأكثرها ظهوراً (التخطيط واللغة) تحتاج إلى الترجمة. وهذا ترتيب عملي يتسق مع مستويات الاختبار الموصوفة في دليل ضمان الجودة الشامل:

  • راجع المتطلبات والتصاميم بحثاً عن قرارات الإعداد المحلي: أي إعدادات محلية، وأي تقويم وأي أرقام لكل منها، وأي الصيغ يستطيع المستخدم تغييرها، ولغة الرجوع الاحتياطي، وما الذي لا يُترجم عمداً (أسماء العلامات التجارية والنصوص القانونية).
  • راجع الكود من ناحية التدويل: نصوص خارجية في ملفات موارد، وواجهات تنسيق واعية بالإعداد المحلي، ولا يسار/يمين فيزيائي في كود التخطيط، وتخزين باليونيكود من طرف إلى طرف.
  • شغّل التوطين الزائف في CI: كل بناء يعمل بالإعداد الزائف، وأي نص إنجليزي عادي عيب.
  • اختبر وظيفياً لكل إعداد محلي ببيانات اختبار موطّنة — أسماء وعناوين وأرقام هواتف ومبالغ وتواريخ بأنظمة الكتابة والصيغ المستهدفة — عبر كل طبقة حتى قاعدة البيانات ثم عائدة إلى التصدير والبريد والرسائل النصية.
  • أجرِ مراجعة لغوية في السياق مع متحدثين أصليين، بلقطات شاشة ومفاتيح النصوص، مقابل المسرد ودليل الأسلوب.
  • نفّذ الانحدار لكل إصدار: اختبارات دخان موطّنة، وفحص المفاتيح الناقصة، ومقارنة لقطات الشاشة لكل إعداد محلي في كل بناء، وجولة توطين كاملة حين تغيّر ميزة شاشات كثيفة النص.
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

جرّبها: مولّد بيانات اختبار متعددة اللغات جرّبها: مولّد بيانات الاختبار العربية جرّبها: مولّد بيانات الاختبار الهندية جرّبها: بيانات اختبار العناوين السعودية

أتمتة فحوص التوطين

يجب أن تعمل الاختبارات المؤتمتة بأكثر من إعداد محلي. اجعل الحزمة معاملية حسب الإعداد المحلي والمنطقة الزمنية، واحسب القيم المتوقعة بواجهات Intl في المنصة بدلاً من كتابة نصوص منسّقة داخل التحققات — فالنصوص المكتوبة يدوياً تفوتها العلامات غير المرئية وتنكسر حين تُحدَّث بيانات CLDR. واحسب القيمة المتوقعة في بيئة التشغيل نفسها التي أنتجت القيمة الفعلية: فمشغّل اختبارات Node.js والمتصفح قد يحملان إصدارين مختلفين من ICU فيختلفان.

ثلاثة فحوص قليلة الكلفة تلتقط معظم حالات الانحدار: فحص للمفاتيح الناقصة يقارن كل ملف إعداد محلي بإعداد المصدر في CI، وفحص لغير المترجم يرصد القيم المطابقة للمصدر (مع قائمة سماح لأسماء العلامات التجارية والرموز)، ومقارنة لقطات الشاشة لكل إعداد محلي في الشاشات الأساسية.

// 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));

جرّبها: مقارنة JSON جرّبها: مولّد بيانات اختبار متعددة اللغات

عيوب توطين نموذجية مكتوبة كعناوين أخطاء

الأمثلة التالية توضيحية وليست حوادث حقيقية. يتبع كل منها نمط تقرير الخطأ: العَرَض والمكان والشرط؛ ويغطي دليل كتابة تقرير الخطأ بقية التقرير.

  • شارة السلة تعرض "2 منتج" بدلاً من "منتجان" — الصيغة مختارة بالشرط count === 1
  • بريد تأكيد الطلب يصل بالإنجليزية للمستخدمين الذين اختاروا العربية في التطبيق
  • منتقي التاريخ الهجري يخزن اليوم السابق حين يُختار التاريخ بين 00:00 و03:00 بتوقيت الرياض
  • حقل المبلغ يرفض "١٥٠٠" المكتوبة بلوحة مفاتيح عربية برسالة "Invalid number"
  • تقرير المبيعات في hi-IN يعرض 1,234,567 بدلاً من 12,34,567
  • اسم منتج هندي مقتطع داخل حرف مركّب يترك علامة حركة بدائرة منقطة في نتائج البحث
  • رسالة التحقق "Field is required" غير مترجمة في نموذج التسجيل العربي

الأسئلة الشائعة

ما الفرق بين اختبار التدويل واختبار التوطين؟

اختبار التدويل يتحقق من أن المنتج يستطيع دعم أي إعداد محلي — نصوص خارجية، وتنسيق واعٍ بالإعداد المحلي، ويونيكود في كل مكان، واتجاه نص غير ثابت — وأفضل ما يُجرى بالتوطين الزائف قبل الترجمة. أما اختبار التوطين فيتحقق من إعداد محلي واحد بعينه: ترجمته في السياق، وصيغه، وتخطيطه، وملاءمته الثقافية.

هل يحتاج اختبار التوطين إلى متحدث أصلي؟

لجودة اللغة، نعم: المصطلحات والنحو وأسلوب الخطاب والطبيعية تحتاج إلى متحدث أصلي مؤهل. أما معظم الفحوص الأخرى — الصيغ والاقتطاع والترميز وصيغ الجمع والنصوص الناقصة والتخطيط — فيستطيع أي مختبِر إجراءها ببيانات الاختبار الصحيحة وقائمة تحقق.

ما التوطين الزائف؟

تحويل آلي للنصوص المصدرية إلى نص بعلامات وممدد ومحاط بأقواس (واختيارياً نص من اليمين إلى اليسار) يُستخدم كإعداد محلي مزيف. يكشف النصوص المكتوبة في الكود والدمج والاقتطاع ومشكلات الترميز قبل وجود أي ترجمة حقيقية.

أي تقويم يجب أن تستخدمه البرمجيات الموجهة للسعودية؟

هذا قرار منتج يُكتب في المتطلبات. توحّد السعودية حساب التقويم الهجري بتقويم أم القرى، والتقويم الميلادي مستخدم على نطاق واسع أيضاً، لذا تعرض منتجات كثيرة الاثنين أو تترك الاختيار للمستخدم. وأياً كان الاختيار، اطلب التقويم صراحةً في الكود واختبره على كل بيئة تشغيل، لأن القيم الافتراضية تتغير بين إصدارات CLDR.

كم صيغة جمع في العربية؟

تعرّف قواعد الجمع في CLDR من يونيكود ست فئات عددية للعربية: zero وone وtwo وfew وmany وother. اختبر أعداداً مثل 0 و1 و2 و3 و11 و100 لتصيبها كلها. وللهندية فئتان: one (للعددين 0 و1) وother.

المراجع

  • Internationalization (i18n) ActivityW3Cمقالات W3C ودروسها وفحوصها في التدويل لبناء محتوى ويب متعدد اللغات واختباره.
  • Unicode CLDR ProjectUnicode Consortiumمستودع بيانات اللغات والمناطق المشترك: بيانات صيغ التاريخ والوقت والأرقام والعملات وقواعد الجمع التي تعتمدها معظم المنصات.
  • The Unicode StandardUnicode Consortiumمجموعة المحارف العالمية وأشكال ترميزها (UTF-8 وUTF-16 وUTF-32) والتطبيع وخصائص كل نقطة ترميز.
  • ECMAScript Internationalization API Specification (ECMA-402)Ecma International (TC39)مواصفة واجهة Intl في JavaScript — التنسيق الواعي باللغة والمنطقة للتواريخ والأرقام والعملات والقوائم وقواعد الجمع في المتصفح.
  • Intl — MDNMDN Web Docs (Mozilla)نطاق Intl عملياً: DateTimeFormat وNumberFormat وCollator وPluralRules، وكيف يعمل التفاوض على اللغة والمنطقة.
  • Time Zone DatabaseIANAقاعدة بيانات tz للمناطق الزمنية في العالم وقواعد فروق التوقيت والتوقيت الصيفي تاريخياً، وتُحدَّث عدة مرات في السنة.
  • ISO 4217 — Currency codesISOرموز العملات ثلاثية الأحرف (SAR وINR وUSD…) ووحداتها الفرعية — المرجع لاختبار حقول العملة وتنسيقها.
  • RFC 5646: Tags for Identifying LanguagesIETF · 2009وسوم اللغات BCP 47 (ar وar-SA وhi-IN وen-GB) — المعرّفات المستخدمة في سمة lang وترويسة Accept-Language وإعدادات اللغة.
  • Indic Layout RequirementsW3C · 2020متطلبات التخطيط للخطوط الهندية مثل الديفاناغاري — الحروف المركبة وعلامات الحركات وتقسيم الأسطر — ذات الصلة بالواجهات الهندية (مسودة عمل من W3C).

تمرين عملي

احكم على نتائج أول جولة لاختبار التوطين

المطلوب

تختبر خدمة توصيل بقالة (مثال خيالي) لها تطبيق Android وموقع ويب في سوقين: السعودية بالإعداد المحلي ar-SA والإنجليزية والأسعار بالريال SAR، والهند بالإعداد المحلي hi-IN والإنجليزية والأسعار بالروبية INR. يضيف الإصدار ⁦2.0⁩ العربية والهندية إلى منتج كان بالإنجليزية فقط. تعرض المادة أدناه قرارات الإعداد المحلي (Locale) من المتطلبات، ومقتطفاً من ملفات الموارد، وعشر ملاحظات من أول جولة توطين في بيئة Staging، منها تشغيل بالإعداد الزائف.

اعمل على الورق مستعيناً بخريطة اختبار التوطين وقائمة التحقق في الدليل. قرارات الإعداد المحلي هي أساس الاختبار (Test basis): احكم على كل ملاحظة بها، وبقواعد الدليل حيث لا تقول شيئاً. ويجيب «عدّاد طول السلاسل النصية» و«عدّاد الأحرف» عن سؤالين، ويساعدك «محوّل المناطق الزمنية» في سؤال ثالث. خصّص لذلك ⁦25–30⁩ دقيقة.

المادة
خدمة توصيل بقالة (مثال خيالي): تطبيق Android وموقع ويب في سوقين
السوق السعودية: الإعدادان المحليان ar-SA (الافتراضي) وen، والعملة SAR،
  والمنطقة الزمنية Asia/Riyadh ⁦(UTC+03:00)⁩
السوق الهندية: الإعدادان المحليان hi-IN (الافتراضي) وen، والعملة INR،
  والمنطقة الزمنية Asia/Kolkata ⁦(UTC+05:30)⁩
يضيف الإصدار ⁦2.0⁩ العربية والهندية، وكانت الخدمة حتى الآن بالإنجليزية فقط.
اليوم: الاثنين 12 أكتوبر 2026. بيئة Staging، البناء ⁦2.0.0-rc1⁩، أول جولة توطين.

قرارات الإعداد المحلي (من المتطلبات)
  القرار LOC-1: في ar-SA أرقام غربية (⁦0–9⁩) وتواريخ ميلادية في كل الشاشات،
    ويعرض تأكيد الطلب أيضاً التاريخ الهجري بتقويم أم القرى.
  القرار LOC-2: في السوق الهندية تُعرض المبالغ بالروبية INR وبالتجميع الهندي
    (⁦12,34,567⁩) في hi-IN وen.
  القرار LOC-3: حقول المبلغ والهاتف والرموز تقبل الأرقام العربية المشرقية وتحوّلها.
  القرار LOC-4: البريد الإلكتروني والرسائل النصية (SMS) والإشعارات بلغة التطبيق
    التي اختارها المستخدم.
  القرار LOC-5: اسم المنتج ⁦40⁩ حرفاً على الأكثر كما يراها المستخدم.
  القرار LOC-6: يجمّع تقرير المبيعات اليومي الطلبات حسب اليوم التقويمي المحلي للسوق.
  مرجع أم القرى: 1 ربيع الآخر 1448 يوافق السبت 12 سبتمبر 2026،
    و1 جمادى الأولى 1448 يوافق الاثنين 12 أكتوبر 2026.

ملفات الموارد (مقتطف؛ رموز التوصيل من 6 أرقام)
  المفتاح cart.items
    الإنجليزية:
      {count, plural, one {# item in your cart} other {# items in your cart}}
    العربية:
      {count, plural,
        one {منتج واحد في السلة}
        other {# منتج في السلة}}
    الهندية:
      {count, plural, one {कार्ट में # आइटम है} other {कार्ट में # आइटम हैं}}
  المفتاح slot.notice
    الإنجليزية: Delivery to {area} between {from} and {to}
    العربية: التوصيل إلى {المنطقة} بين {from} و{to}
  المفتاح wallet.invalidAmount
    الإنجليزية: Invalid number
    العربية: (لا يوجد مُدخل)
  المفتاح sms.deliveryCode
    الإنجليزية:
      Your delivery code is {code}. Share it only with the courier at your door.
    الهندية:
      आपका डिलीवरी कोड {code} है। यह कोड केवल डिलीवरी पार्टनर को बताएँ, किसी और को नहीं।

الملاحظات (بيئة Staging، البناء ⁦2.0.0-rc1⁩)
  الملاحظة O1، ar-SA، السلة: عدد المنتجات 0 يعرض «0 منتج في السلة»،
    و2 يعرض «2 منتج في السلة»، و3 يعرض «3 منتج في السلة»، و11 يعرض «11 منتج في السلة».
  الملاحظة O2، ar-SA، شاشة موعد التوصيل: «التوصيل إلى {المنطقة} بين 18:00 و20:00».
  الملاحظة O3، تشغيل بالإعداد الزائف English (XA) على Android،
    وهو يضيف علامات على الحروف وكلمات حشو وأقواساً:
    زر الدفع: ⁦Place order⁩
    ملخص الطلب: ⁦[Ýöû šåVé one two] 15.00 SAR [öñ ţĥîš öŕðéŕ one two]⁩
    التبويب الرابع في شريط التبويبات: ⁦[Öŕðéŕ ĥîšţ⁩
  الملاحظة O4، ar-SA، شحن المحفظة: «١٥٠» المكتوبة بلوحة مفاتيح عربية تُرفض برسالة
    «Invalid number» (بالإنجليزية)، أما «150» فتُقبل.
  الملاحظة O5، السوق الهندية، لغة التطبيق الهندية ولغة الهاتف الإنجليزية:
    تصل الرسالة النصية لرمز التوصيل بالإنجليزية.
  الملاحظة O6، لوحة الإدارة على الويب بواجهة هندية: يُرفض اسم المنتج
    «⁦बासमती सेला चावल⁩» برسالة «⁦नाम 40 अक्षरों से लंबा है⁩»
    (أي: الاسم أطول من ⁦40⁩ حرفاً).
  الملاحظة O7، تقرير المبيعات اليومي للسوق السعودية ليوم الثلاثاء 6 أكتوبر 2026
    يتضمن الطلب ORD-48213، وقد أنشأه العميل يوم الأربعاء 7 أكتوبر الساعة 01:30
    بتوقيت الرياض، وقيمة created_at هي ⁦2026-10-06T22:30:00Z⁩.
  الملاحظة O8، ar-SA، تأكيد طلب أُنشئ يوم الأحد 11 أكتوبر 2026:
    «الأحد، ١١ أكتوبر ٢٠٢٦ (٢٨ ربيع الآخر ١٤٤٨ هـ)»
  الملاحظة O9، السوق الهندية، إجمالي تقرير المبيعات الشهري: في hi-IN «⁦₹1,234,567.50⁩»،
    وفي en «⁦₹12,34,567.50⁩». وسجّل رافي (مختبِر) قيمة en عيباً بعنوان «wrong grouping».
  الملاحظة O10، السوق السعودية، قسيمة التوصيل للمندوب (PDF): اسم العميل
    «نورة القحطاني» يُطبع «???? ????????»، بينما تعرض لوحة الإدارة الاسم نفسه صحيحاً.
الخطوات
  1. قرّر لكل ملاحظة: هل هي عيب (اذكر قرار الإعداد المحلي أو قاعدة الدليل)؟ وهل هو عيب تدويل (i18n) أم عيب توطين (l10n)؟ وإلى أي مجال في خريطة الدليل ينتمي؟ بعض الملاحظات تحوي أكثر من نتيجة، وإحداها تحوي بلاغاً ليس عيباً.
  2. للملاحظة O1 اكتب الرسالة العربية المصحّحة وجدول اختبار صيغ الجمع لها: كل عدد، وفئة CLDR التي يصيبها، والنص المتوقع. ثم اذكر الأعداد التي يحتاج إليها الجدول الهندي.
  3. قِس: اسم المنتج في O6 بـ«عدّاد طول السلاسل النصية» (لماذا رُفض؟)، والرسالة النصية الهندية في O5 مع رمز من 6 أرقام بـ«عدّاد الأحرف» (ماذا يعني طولها؟).
  4. احسب القيم المتوقعة للملاحظتين O7 وO8: يوم التقرير الذي ينتمي إليه الطلب ORD-48213، والساعات المتأثرة في كل سوق، وتاريخ أم القرى ليوم 11 أكتوبر 2026.
  5. اكتب عنوان تقرير خطأ لكل عيب (العَرَض والمكان والشرط)، ثم سمِّ أرخص فحص أبكر كان سيكتشف كل مجموعة من العيوب.
إظهار الإجابة النموذجية
الإجابة النموذجية

أساس الاختبار والنتيجة العامة. القرارات من LOC-1 إلى LOC-6 هي أساس الاختبار، وحيث لا تقول شيئاً تنطبق قواعد الدليل. تحوي الملاحظات العشر 14 عيباً، وبلاغاً واحداً ليس عيباً (تجميع en في O9)، وسؤالاً مفتوحاً لمالك المنتج (طول الرسالة النصية في O5). منها 11 عيباً من عيوب التدويل (i18n): تعيش في الكود — نص مكتوب في الكود، أو جملة مدموجة، أو خطوة تحليل أو تنسيق أو تحويل تتجاهل الإعداد المحلي — ويصلحها مطوّر. و3 عيوب توطين (l10n): تعيش في موارد إعداد محلي واحد (O1 وO2 والرسالة العربية الناقصة في O4)، ويصلحها المترجم.

O1: عيب توطين (l10n) في جودة اللغة والترجمة (صيغ الجمع). صيغة الرسالة سليمة: الإنجليزية والهندية تستخدمان فئات الجمع في ICU، وICU يختار فئة CLDR المناسبة لكل عدد. لكن المورد العربي لا يقدّم إلا one وother، فيرجع كل عدد غير 1 إلى other: العدد 2 يحتاج إلى المثنى «منتجان»، و3 إلى الجمع «منتجات»، و11 إلى التمييز المنصوب «منتجًا»، و0 إلى صيغة خاصة به. أصلح ar.json بالفئات الست كما في الدليل: {count, plural, zero {السلة فارغة} one {منتج واحد في السلة} two {منتجان في السلة} few {# منتجات في السلة} many {# منتجًا في السلة} other {# منتج في السلة}}. العنوان: رسالة السلة العربية تعرض «2 منتج في السلة» بدلاً من «منتجان في السلة»، لأن cart.items في المورد العربي لا يحوي إلا الصيغتين one وother.

جدول اختبار صيغ الجمع في ar-SA (العدد، فئة 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 आइटम हैं». وفي الهندية يأخذ الصفر صيغة one، فاسأل المترجم هل تُقرأ «कार्ट में 0 आइटम है» قراءة طبيعية، أو أضف حالة لقيمة محددة مثل =0 {कार्ट ख़ाली है}.

O2: عيب توطين (l10n) في جودة اللغة والترجمة (معاملات الرسائل). ترجم المترجم اسم المعامل {area} إلى {المنطقة}. والتطبيق يمرّر قيمة باسم area، فلا تجد أداة التنسيق قيمة لـ{المنطقة} فتطبع الأقواس كما هي. أصلح ar.json لتبقى {area} في الرسالة دون تغيير. ثم ابحث عن المشكلة نفسها في كل مكان: فحص آلي يتأكد أن كل ترجمة تحوي المعاملات نفسها التي في المصدر الإنجليزي بالضبط يجد كل هذه الرسائل دفعة واحدة. العنوان: إشعار موعد التوصيل يعرض «{المنطقة}» كما هي بدلاً من اسم المنطقة في ar-SA، لأن اسم المعامل مترجم في slot.notice.

O3: ثلاثة عيوب تدويل (i18n) اكتُشفت قبل أن يقرأ أحد أي ترجمة، تماماً كما يتوقع جدول التوطين الزائف في الدليل: اثنان في جودة اللغة والترجمة (نص مكتوب في الكود، وجملة مدموجة)، وواحد في التخطيط (تمدد النص). النص «Place order» بالإنجليزية العادية مكتوب في الكود: لم يمر قط بملفات الموارد، وسيبقى إنجليزياً في العربية والهندية. وملخص الطلب يعرض قطعتين بين أقواس حول المبلغ: الجملة مدموجة من «You save» والمبلغ و«on this order»، وتحتاج إلى رسالة واحدة بمعامل مثل You save {amount} on this order، مع تنسيق المبلغ بحسب الإعداد المحلي. والتبويب الرابع فقد قوسه الختامي: التسمية مقتطعة، فلا مساحة لترجمات أطول؛ افحص شريط التبويبات بالتسميات العربية والهندية الحقيقية أيضاً. العناوين: نص زر «Place order» مكتوب في الكود وليس في ملفات الموارد؛ سطر «You save … on this order» في ملخص الطلب مركّب بالدمج؛ تسمية التبويب الرابع (Order history) مقتطعة في الإعداد الزائف.

O4: عيبان. الأول عيب تدويل (i18n) في الصيغ المحلية (الأعداد والأرقام): ينص LOC-3 على قبول الأرقام العربية المشرقية وتحويلها، والحقل يرفضها. اختبر حقلي الهاتف والرمز أيضاً لأن LOC-3 يشملهما، واسأل مالك المنتج هل تُقبل الفاصلة العشرية العربية (١٥٠٫٥٠). والثاني عيب توطين (l10n) في جودة اللغة والترجمة (نص غير مترجم): المفتاح wallet.invalidAmount موجود في en.json وغائب عن ar.json، فيرجع التطبيق إلى الإنجليزية. وفحص المفاتيح الناقصة يجد كل مفتاح مثله: السكربت الوارد في الدليل يُفشل البناء في CI بسببها، وأداة «مقارنة JSON» بين en.json وar.json تعرضها مفاتيحَ محذوفة (وتظهر كل قيمة مترجمة قيمةً متغيرة). العنوانان: حقل مبلغ شحن المحفظة يرفض «١٥٠» المكتوبة بالأرقام العربية المشرقية في ar-SA؛ رسالة التحقق «Invalid number» غير مترجمة في شاشة شحن المحفظة في ar-SA.

O5: عيب تدويل (i18n) في اختيار الإعداد المحلي: يشترط LOC-4 لغة التطبيق التي اختارها المستخدم، لكن الرسالة النصية تتبع لغة الهاتف. والقالب الهندي موجود، فالمشكلة ليست ترجمة ناقصة: خدمة الرسائل لا تتلقى لغة المستخدم في التطبيق. افحص البريد الإلكتروني والإشعارات للمستخدم نفسه، ومستخدمي العربية الذين لغة هواتفهم الإنجليزية. ثم قِس الرسالة الهندية مع رمز من 6 أرقام بـ«عدّاد الأحرف»: يعرض شريط «SMS (Unicode)» القيمة ⁦82 / 70⁩، أي بزيادة 12، لأنه يعدّ وحدات UTF-16 (أما رقم «الأحرف» فأقل، لأنه يعدّ العناقيد الرسومية). النص بالديفاناغاري يُرسل عادةً بترميز UCS-2 الذي تتسع فيه الرسالة الواحدة لـ 70 محرفاً (وحدة UTF-16)، فتُرسل هذه الرسالة في رسالتين؛ أما النص الإنجليزي فطوله 74 محرفاً بأبجدية GSM ذات السبعة بتات ⁦(74 / 160)⁩ ويتسع في رسالة واحدة. ولا يحدد أي متطلب حداً، فهذا ليس إخفاقاً: اطرحه سؤالاً على مالك المنتج، لأن مزوّدي الخدمة يحتسبون عادةً كل جزء رسالةً مستقلة، واقترح صياغة هندية لا تزيد على 70 محرفاً. العنوان: رسالة رمز التوصيل النصية تُرسل بالإنجليزية للمستخدمين الذين لغة تطبيقهم الهندية ولغة هاتفهم الإنجليزية.

O6: عيب تدويل (i18n) في معالجة النص وأنظمة الكتابة (الطول). يعطي «عدّاد طول السلاسل النصية» للاسم 11 عنقوداً رسومياً (Grapheme cluster)، و16 نقطة ترميز، و16 وحدة UTF-16، و44 بايت UTF-8. والعدد الوحيد الذي يتجاوز 40 هو عدد البايتات، فالفحص يعدّ بايتات UTF-8، بينما يعدّ LOC-5 المحارف كما يراها المستخدم، أي العناقيد الرسومية: يجب قبول الاسم. أضف اختبارات حدّية بأسماء بالديفاناغاري من 40 و41 عنقوداً رسومياً، واسأل عن وحدة عمود قاعدة البيانات وحجمه، لأن الاسم الهندي ذا الأربعين عنقوداً قد يحوي نقاط ترميز أكثر بكثير، ولكل منها حتى ثلاثة بايتات في UTF-8. العنوان: نموذج المنتج في لوحة الإدارة يرفض اسم منتج هندياً من 11 محرفاً لأنه «أطول من 40 حرفاً»، والحد محسوب ببايتات UTF-8.

O7: عيب تدويل (i18n) في الصيغ المحلية (الأوقات والمناطق الزمنية). اللحظة ⁦2026-10-06T22:30:00Z⁩ هي الساعة 01:30 يوم الأربعاء 7 أكتوبر بتوقيت الرياض ⁦(UTC+03:00)⁩، كما يؤكد «محوّل المناطق الزمنية». يجمّع التقرير الطلبات حسب تاريخ 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 بالتوقيت المحلي في السوقين؛ وقارن إجمالي كل يوم بمجموع طلبات ذلك اليوم. العنوان: تقرير المبيعات اليومي للسوق السعودية يضع الطلبات المنشأة بين 00:00 و02:59 بتوقيت الرياض في اليوم السابق، لأنه يجمّع حسب تاريخ UTC.

O8: عيبا تدويل (i18n) في الصيغ المحلية (التواريخ والتقاويم). الأول: الأرقام عربية مشرقية مع أن LOC-1 يشترط الأرقام الغربية. والأرجح أن الكود يطلب ar-SA وحده، وقيمته الافتراضية في بيانات CLDR الحديثة هي الأرقام العربية المشرقية؛ فعليه أن يطلب نظام الأرقام صراحةً (ar-SA-u-nu-latn، وar-SA-u-ca-islamic-umalqura-nu-latn للتاريخ الهجري)، وأن يُختبر على كل بيئة تشغيل تنسّق التواريخ: الخادم للبريد وملفات PDF، وAndroid، والمتصفحات. الثاني: التاريخ الهجري خاطئ. فالأول من ربيع الآخر 1448 يوافق 12 سبتمبر، والأول من جمادى الأولى يوافق 12 أكتوبر، إذن 11 أكتوبر هو آخر أيام ربيع الآخر: اليوم 30، بعد 29 يوماً من 12 سبتمبر. والرقم 28 هو ما يعطيه الحساب الهجري الجدولي المدني (التقويم islamic-civil في ICU) لذلك اليوم، فالكود يستخدم حساباً غير أم القرى. المتوقع: «الأحد، 11 أكتوبر 2026 (30 ربيع الآخر 1448 هـ)». وأضف إلى بيانات الاختبار نهايات أشهر ونهاية سنة في التقويمين. العنوانان: تأكيد الطلب في ar-SA يعرض التواريخ بالأرقام العربية المشرقية بدلاً من الأرقام الغربية؛ تأكيد الطلب يعرض التاريخ الهجري 28 ربيع الآخر 1448 ليوم 11 أكتوبر 2026 بدلاً من تاريخ أم القرى 30 ربيع الآخر 1448.

O9: عيب واحد وبلاغ واحد غير صالح. وفق LOC-2 يجب أن يعرض hi-IN القيمة ⁦₹12,34,567.50⁩؛ أما ⁦₹1,234,567.50⁩ فتجميع غربي، أي أن التقرير ينسّق مبالغ hi-IN بإعداد محلي آخر أو بنمط ثابت (عيب تدويل في الصيغ المحلية). وقيمة en، ⁦₹12,34,567.50⁩، هي بالضبط ما يشترطه LOC-2 للسوق الهندية: ارفض بلاغ رافي لأن السلوك مطابق للمواصفات، واقتبس LOC-2. العنوان: تقرير المبيعات الشهري في hi-IN يعرض ⁦₹1,234,567.50⁩ بدلاً من ⁦₹12,34,567.50⁩.

O10: عيب تدويل (i18n) في معالجة النص (الترميز). علامات الاستفهام تعني أن المحارف ضاعت في تحويل إلى ترميز لا يحوي الحروف العربية؛ أما الخط الذي لا يحوي الرسوم فيعرض مربعات فارغة، وأما UTF-8 المقروء بترميز أحادي البايت فيعرض رموزاً لاتينية مشوّهة مثل «Ø». وعلامة استفهام واحدة لكل حرف (4 ثم 8) تطابق هذا الضياع. ولوحة الإدارة تعرض الاسم صحيحاً، فالقيمة المخزّنة سليمة على الأرجح، والضياع يحدث في الطريق إلى ملف PDF: في خدمة القسائم أو في مكتبة PDF التي تستخدمها. اختبر أيضاً أسماء هندية في قسيمة السوق الهندية، واسماً يخلط بين نظامي كتابة. العنوان: قسيمة التوصيل للمندوب (PDF) تطبع أسماء العملاء العربية علامات استفهام.

أرخص الفحوص الأبكر. كان التوطين الزائف في CI سيكتشف كل ما في O3 من أول بناء، قبل أي ترجمة. وكانت الفحوص الآلية على ملفات الموارد ستكتشف عيوب التوطين يوم وصول الترجمات: المفاتيح الناقصة (O4)، والمعاملات المختلفة عن المصدر (O2)، ورسائل الجمع التي تنقصها فئات CLDR للغة الهدف (O1). أما عيوب التدويل الأخرى (تحليل الأرقام في O4، ومن O5 إلى O10) فهي كود لا يراعي الإعداد المحلي: تجدها مراجعة الكود من ناحية التدويل، وتجدها كذلك قبل أي جولة يدوية الاختباراتُ الوظيفية لكل إعداد محلي ببيانات اختبار موطّنة — أرقام عربية مشرقية، وأسماء بالديفاناغاري، وأوقات قريبة من منتصف الليل، ونهاية شهر في تقويم أم القرى، ومبالغ كبيرة بالروبية، وأسماء عربية وهندية تمر حتى ملف PDF والرسالة النصية — فاحتفظ بها اختبارات انحدار. أما طول الرسالة النصية فمكانه مراجعة المتطلبات: حد أقصى للطول لكل قالب ولكل لغة.

إن اختلفت إجاباتك فراجعها مقابل قاعدتين من الدليل: عيب التدويل يعيش في الكود ويصلحه مطوّر، وعيب التوطين يعيش في محتوى إعداد محلي واحد ويُصلَح في مورده؛ والملاحظة لا تكون عيباً إلا إذا خالفت قرارات الإعداد المحلي أو قاعدة ينص عليها الدليل. وتصنيف O8 أو O9 عيبَ توطين لأنهما يظهران في إعداد محلي واحد مقبول إن وضع تقريرك الإصلاح في الكود؛ أما الإبلاغ عن تجميع en في O9 أو عن طول الرسالة النصية في O5 بوصفه إخفاقاً فغير مقبول.

تقدّمك في هذا الموضوع

جزء من مسار تعلم ضمان الجودة

الأدوات المذكورة في هذا الدليل

ولّد أسماء وعناوين وجملاً وأرقاماً عربية (بالأرقام العربية-الهندية) وحالات حدّية للكتابة من اليمين إلى اليسار لاختبار التوطين.

بيانات الاختبار

ولّد سلاسل نصية اختبارية بترميز Unicode عبر الخطوط (العربية والديفاناغارية وCJK والسيريلية) والرموز التعبيرية وعلامات الدمج وصيغ التطبيع.

بيانات الاختبار

ولّد مجموعات بيانات للتواريخ: تواريخ عشوائية ضمن نطاق، وأيام كبيسة، ونهايات الأشهر، وحدود التوقيت الصيفي، وصيغ متعددة.

بيانات الاختبار

حوّل التاريخ والوقت بين المناطق الزمنية (الرياض، عمّان، دلهي، UTC، نيويورك، لندن…).

أدوات مساعدة

ولّد بيانات اختبار بنمط العنوان الوطني السعودي: رقم المبنى والشارع والحي والمدينة والرمز البريدي والرقم الإضافي.

بيانات الاختبار

ولّد مدخلات مليئة بالأحرف الخاصة: علامات الاقتباس، والأحرف الوصفية لـ SQL/HTML/JSON، وأحرف التحكم، والرموز التعبيرية، وحيل المسارات.

بيانات الاختبار

مقارنة مستندي JSON دلالياً وإبراز القيم المضافة والمحذوفة والمتغيرة.

JSON والبيانات

كيف تساعدك متقن سوفت

أدلة أخرى

أدلة أخرى
بيانات الاختبار

اختبار الواجهات من اليمين إلى اليسار

كيف تختبر الواجهات العربية من اليمين إلى اليسار: سمتا dir وlang، وما يُعكس وما لا يُعكس، وخصائص CSS المنطقية، والنص ثنائي الاتجاه، والعرض العربي والنماذج.

وقت القراءة 11 دقائق
تصميم الاختبارات

اختبار إمكانية الوصول

اختبار إمكانية الوصول وفق WCAG 2.2: مبادئ POUR، والمستويات A وAA وAAA، ومنهجية WCAG-EM، واليدوي مقابل الآلي، والممارسة في السبرنت وCI، والعيوب الشائعة.

وقت القراءة 14 دقائق
تصميم الاختبارات

سيناريوهات اختبار تطبيقات الجوال

سيناريوهات اختبار جاهزة للجوال: التثبيت والتحديث، والأذونات، والمقاطعات، وتغيّر الشبكة، والمزامنة دون اتصال، والموارد، والإشعارات، والإيماءات.

وقت القراءة 10 دقائق
تصميم الاختبارات

ضمان جودة المنتج من البداية إلى النهاية

ما الذي يشمله ضمان الجودة الشامل — مراجعة المتطلبات وتصميم الاختبارات والاختبار الوظيفي واختبار الأداء والأمان وبوابات الإصدار والمقاييس — وكيف تنفّذه.

وقت القراءة 8 دقائق
قواعد البيانات

اختبار قواعد البيانات لمهندسي الجودة

كيف تختبر قاعدة البيانات: التحقق من عمليات CRUD عبر الواجهة وAPI، والقيود، والسلامة المرجعية، والاتساق، وبيانات الاختبار، والأداء والأمن.

وقت القراءة 13 دقائق
تحليل الأخطاء

كيف تكتب تقرير خطأ (Bug Report)

كيف تكتب تقرير خطأ يستطيع المطورون التصرف بناءً عليه: الحقول المهمة، ونموذج جاهز للنسخ، ومثال كامل، والفرق بين الخطورة والأولوية، والأخطاء الواجب تجنبها.

وقت القراءة 4 دقائق