اختبار الروابط العميقة

الرابط العميق (Deep Link) رابط يفتح شاشة محددة داخل تطبيق الجوال بدلاً من شاشته الأولى. فالنقر على https://shop.example.com/orders/A-1042 في رسالة شحن بالبريد الإلكتروني يجب أن يعرض الطلب A-1042 في تطبيق المتجر. وتصل الروابط إلى المستخدمين عبر البريد الإلكتروني والرسائل النصية ورموز QR والإشعارات الفورية والتطبيقات الأخرى، وكل رابط منها نقطة دخول تتجاوز التنقل المعتاد في التطبيق.

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

لماذا يهم

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

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

مثبّت أم لا، مسجّل الدخول أم لا

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

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

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

جرّبها: مولّد الاختبار الزوجي (Pairwise)

تشغيل الروابط والتحقق من الربط

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

وللفحوص السريعة القابلة للتكرار استخدم أدوات المنصة. في Android يطلق adb رابطاً ويترك للنظام اختيار التطبيق الذي يعالجه، ومنذ Android 12 يعرض حالة التحقق من النطاق ويعيد تشغيلها. وفي محاكي iOS يفتح simctl عنوان URL، أما على iPhone حقيقي فالصق الرابط في Notes أو Messages وانقر عليه.

# Android: fire the link and let the system choose the app (no package name)
adb shell am start -W -a android.intent.action.VIEW \
  -c android.intent.category.BROWSABLE \
  -d "https://shop.example.com/orders/A-1042"

# Android 12+: domain verification state, then a fresh verification
adb shell pm get-app-links com.example.shop
adb shell pm verify-app-links --re-verify com.example.shop

# iOS Simulator: open the link through the system
xcrun simctl openurl booted "https://shop.example.com/orders/A-1042"

جرّبها: فاحص إعادة التوجيه

مثال تطبيقي: رابط الطلب في رسالة الشحن

المتطلب: «تتضمن رسالة الشحن رابطاً إلى الطلب. مع التطبيق يفتح الرابط تفاصيل الطلب، ومن دونه يفتح صفحة الطلب على الموقع». الرابط هو https://shop.example.com/orders/A-1042 والطلب يخص سارة. ابدأ بجدول قرار (Decision table) على أربعة شروط من نوع صحيح أو خطأ: مثبّت، ومتحقَّق منه، ومسجّل الدخول، والمالك. وكل عمود في الجدول توليفة واحدة من هذه الشروط الأربعة مع الشاشة التي يجب أن يفتحها الرابط، والأعمدة تعطي الحالات الأساسية؛ ويشرح درس اختبار جداول القرار كيف تبني الجدول وتدمج الأعمدة التي لا يغيّر فيها شرطٌ النتيجة. ثم أضف تنويعات حالة التشغيل والقناة إلى الأعمدة الأعلى مخاطرة بدلاً من مضاعفة كل شيء.

  • مثبّت، وسارة مسجّلة الدخول، والتطبيق مغلق: يُفتح الطلب A-1042، ويقود زر الرجوع إلى قائمة الطلبات كما اتُّفق.
  • الحالة نفسها والتطبيق في الخلفية على شاشة السلة: يُفتح الطلب A-1042 وتبقى السلة دون تغيير.
  • مثبّت وغير مسجّل الدخول: تظهر شاشة تسجيل الدخول، وبعد دخول سارة يُفتح الطلب A-1042 لا الشاشة الرئيسية.
  • مثبّت ومستخدم آخر مسجّل الدخول: رسالة بأن الطلب غير متاح، ولا بيانات من A-1042، وترفض الواجهة البرمجية (API) إرجاع بيانات الطلب A-1042.
  • غير مثبّت: تُفتح صفحة الطلب على الموقع (بعد تسجيل الدخول على الويب) مع رابط إلى المتجر، ولا صفحة 404.
  • نسخة موقّعة بمفتاح غير مذكور في assetlinks.json: يُفتح الموقع ولا يُظهر pm get-app-links النطاق بالحالة verified. أبلغ عنه على الإعدادات لا على الشاشة.
  • معرّف مجهول أو فارغ أو طويل جداً (/orders/A-9999 و/orders/ ومعرّف من 300 حرف): شاشة خطأ واضحة دون انهيار.
  • رسالة البريد الحقيقية، عبر إعادة توجيه تتبّع النقرات، في كل تطبيق بريد مدعوم: النتيجة نفسها كما مع الرابط النظيف.

جرّبها: مولّد جداول القرار جرّبها: مولّد حالات الاختبار

أخطاء شائعة

  • الاختبار والتطبيق مثبّت والمستخدم مسجّل الدخول فقط، وهي الحالة الوحيدة التي جرّبها المطورون أصلاً.
  • إطلاق الروابط عبر adb موجّهاً إلى حزمة التطبيق فقط، أو كتابتها في المتصفح، فيتجاوز ذلك معالجة المنصة للروابط أو يغيّرها؛ انقرها حيث ينقرها المستخدمون.
  • الإبلاغ عن «فُتح الموقع» كعيب في التطبيق دون التحقق من الربط أولاً؛ فالسبب عادةً ملف الربط أو البصمة أو إعادة توجيه.
  • قبول الشاشة الرئيسية بعد تسجيل الدخول نتيجةً ناجحة: المستخدم أراد الطلب، فالوصول إلى أي مكان آخر فشل.
  • نسيان نسخ التطبيق الأقدم، التي ما زالت تستقبل الروابط، وتستقبل في iOS ملف الربط الحالي أيضاً.
  • الوثوق بمعاملات الرابط: يجب ألا يتجاوز الرابط تسجيل الدخول، أو يعرض بيانات مستخدم آخر، أو يدفع أو يحذف أو يرسل شيئاً دون تأكيد.

من منظور ضمان الجودة

اطلب مبكراً جرداً للروابط العميقة: كل رابط يرسله المنتج أو يطبعه، ونمط عنوانه، والشاشة الهدف، والمسار البديل (Fallback)، ومن يملك ملفات الربط. واتفق مع المطورين ومالك المنتج على وجهة زر الرجوع بعد الرابط، وما يظهر عند مسار مجهول، وهل الربط العميق المؤجَّل ضمن النطاق. وأضف فحص ملفي الربط إلى قائمة تحقق الإصدار، لأن نشر تحديث للموقع قد يعطّل الروابط دون أي تغيير في التطبيق.

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

تمرين عملي

صمّم اختبارات الروابط العميقة لرسالة عرض ترويجي

المطلوب

يرسل متجر الرسالة النصية أدناه. العروض متاحة للجميع، لكن رمز الخصم لا يُطبَّق إلا على سلة مستخدم مسجّل الدخول، وقد ينتهي العرض قبل أن ينقر المستخدم الرابط.

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

المادة
الرسالة النصية:
رمز خصم 10% بانتظارك: https://shop.example.com/offers/ramadan?code=SAVE10

القاعدة:
مع التطبيق: يفتح الرابط شاشة العرض ويطبّق الرمز على السلة.
بدون التطبيق: يفتح صفحة العرض على الموقع الإلكتروني.
الخطوات
  1. اكتب الحالات: مثبّت أم لا، متحقَّق منه أم لا، التطبيق مغلق أم في الخلفية، المستخدم مسجّل الدخول أم لا.
  2. اكتب النتيجة المتوقعة لكل توليفة ذات معنى، بما في ذلك ما يحدث لرمز الخصم.
  3. أضف المدخلات غير الصالحة: رمز مفقود أو مجهول أو بأحرف صغيرة، وعرض انتهى.
  4. اكتب الفحوص التي تفصل خللاً في الإعدادات عن عيب في التطبيق.
إظهار الإجابة النموذجية
الإجابة النموذجية

مثبّت ومسجّل الدخول، والتطبيق مغلق ثم في الخلفية: تُفتح شاشة العرض وتُظهر السلة الرمز SAVE10 مطبّقاً مرة واحدة؛ والنقر على الرابط مرة ثانية لا يطبّقه مرتين.

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

غير مثبّت: تُفتح صفحة العرض على الموقع مع الرمز، وطريقة للحصول على التطبيق، ولا صفحة 404. والاحتفاظ بالرمز عبر التثبيت من المتجر هو ربط عميق مؤجَّل يحتاج إلى متطلب خاص به.

المدخلات غير الصالحة: غياب المعامل code، ورمز مجهول، وsave10 بأحرف صغيرة (يُقبل أو يُرفض كما تنص القواعد)، وعرض منتهٍ، كلٌّ منها يعطي رسالة واضحة؛ والرمز الخاطئ لا يُفرغ السلة أبداً.

مثبّت لكن غير متحقَّق منه: تُفتح صفحة العرض على الموقع بدلاً من التطبيق، وهذا خلل في الإعدادات لا عيب في التطبيق. وقبل أن تنسب هذا الفشل أو غيره إلى التطبيق أجرِ الفحوص: انقر الرابط في تطبيق الرسائل لا في المتصفح؛ وشغّل pm get-app-links على Android؛ وتأكد أن ملفي الربط يُحمَّلان عبر HTTPS دون إعادة توجيه، وأن ملف iOS يغطي /offers/* وأن مرشّح النوايا في Android يعلن هذا المسار؛ وتتبّع أي أداة تقصير روابط بحثاً عن إعادة توجيه عبر نطاق آخر.

أسئلة شائعة

ما الفرق بين الرابط العميق وApp Link والرابط العام (Universal Link)؟

الرابط العميق أي رابط يفتح مكاناً محدداً في التطبيق. وAndroid App Links والروابط العامة في iOS روابط عميقة تستخدم عناوين https عادية على نطاق تحققت المنصة من ارتباطه بالتطبيق، فتفتح التطبيق إن كان مثبّتاً والموقع إن لم يكن. أما رابط المخطط المخصص مثل shop:// فرابط عميق بلا هذا التحقق.

لماذا يفتح الرابط الموقع والتطبيق مثبّت؟

غالباً لأن المنصة لم تتحقق من النطاق لهذه النسخة: البصمة في assetlinks.json لا تطابق مفتاح التوقيع، أو أحد الملفين مفقود أو غير صالح أو يُعاد توجيهه، أو النطاق غير مذكور في مرشّح النوايا أو في Associated Domains. وفي iOS هذا متوقع أيضاً إذا كُتب العنوان في Safari أو نُقر على صفحة من الموقع نفسه. تحقق من حالة الربط قبل الإبلاغ.

هل أستطيع اختبار الروابط العميقة على المحاكيات؟

كثير من الفحوص نعم: يعمل adb على محاكي Android ويعمل xcrun simctl openurl على محاكي iOS. لكن احتفظ بجولة واحدة على الأقل على أجهزة حقيقية مع القنوات الحقيقية، مثل تطبيقات البريد والمتصفحات الداخلية وماسح QR في الكاميرا والتثبيت من المتجر، لأنها تتصرف هناك بشكل مختلف أو لا توجد إلا هناك.

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

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

المراجع

  • About App LinksAndroid Developers (Google)روابط App Links في Android: روابط عميقة إلى موقعك يتحقق منها النظام عبر ملف Digital Asset Links (assetlinks.json)، فتفتح التطبيق مباشرةً.
  • Allowing apps and websites to link to your contentAppleالروابط العامة (Universal Links) على منصات Apple: روابط ويب عادية تفتح التطبيق إن كان مثبّتاً — بعد أن يتحقق النظام من ملف على موقعك — وتفتح الموقع إن لم يكن.
  • OWASP Mobile Application Security Testing Guide (MASTG)OWASP Foundationدليل الاختبار المرافق لـ MASVS: تقنيات وحالات اختبار للتحقق من أمان تطبيقات الجوال.
  • OWASP Mobile Application Security Verification Standard (MASVS)OWASP Foundationمتطلبات OWASP الأمنية لتطبيقات الجوال، مجمّعة في مجالات ضبط مثل التخزين والتشفير والمصادقة والشبكة والتفاعل مع المنصة.

تدرّب بأدوات متقن

أنشئ جداول القرار من الشروط والإجراءات، وولّد جميع تركيبات القواعد، واختزل المستحيل منها.

تصميم الاختبارات

تفكيك عنوان URL إلى البروتوكول والمضيف والمنفذ والمسار ومعاملات الاستعلام والجزء (fragment) وبيانات الاعتماد.

الويب

التحقق من صحة صياغة JSON مع تحديد مواقع الأخطاء بدقة واقتراحات مفيدة للإصلاح.

JSON والبيانات

تتبّع سلاسل إعادة التوجيه (301/302/307/308) وعرض كل قفزة وحالتها وعنوان URL النهائي.

الويب

ولّد حالات اختبار منظّمة (المعرّف والعنوان والشروط المسبقة والخطوات والنتيجة المتوقّعة والأولوية) من وصف الميزة وقائمة الحقول.

تصميم الاختبارات

للتعمّق أكثر

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

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