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

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

ليست كل اختبارات الوحدات محلية، وليست كل الاختبارات الشاملة يتم تشغيلها على جهاز. على سبيل المثال:
- الاختبار المحلي الكبير: يمكنك استخدام محاكي Android يعمل محليًا، مثل Robolectric.
- الاختبار الصغير الذي يتضمّن أدوات: يمكنك التأكّد من أنّ الرمز البرمجي يعمل بشكل جيد مع إحدى ميزات إطار العمل، مثل قاعدة بيانات SQLite. يمكنك إجراء هذا الاختبار على أجهزة متعددة للتحقّق من عملية الدمج مع إصدارات متعددة من SQLite.
أمثلة
توضّح المقتطفات التالية كيفية التفاعل مع واجهة المستخدم في اختبار واجهة مستخدم مزوَّد بأدوات ينقر على أحد العناصر ويتأكّد من عرض عنصر آخر.
Espresso
// When the Continue button is clicked
onView(withText("Continue"))
.perform(click())
// Then the Welcome screen is displayed
onView(withText("Welcome"))
.check(matches(isDisplayed()))
واجهة مستخدم الإنشاء
// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()
// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()
يعرض هذا المقتطف جزءًا من اختبار وحدة لـ ViewModel (اختبار محلي على الجهاز المضيف):
// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)
// When data is loaded
viewModel.loadData()
// Then it should be exposing data
assertTrue(viewModel.data != null)
بنية قابلة للاختبار
في بنية التطبيق القابلة للاختبار، يتّبع الرمز البرمجي بنية تتيح لك اختبار أجزاء مختلفة منه بسهولة بشكل منفصل. تتضمّن التصاميم المعمارية القابلة للاختبار مزايا أخرى، مثل تحسين قابلية القراءة والصيانة والتوسّع وإعادة الاستخدام.
تؤدي البنية غير القابلة للاختبار إلى ما يلي:
- اختبارات أكبر وأبطأ وأكثر تقطعًا قد تحتاج الفئات التي لا يمكن إجراء اختبارات الوحدة لها إلى تغطيتها باختبارات دمج أو اختبارات واجهة مستخدم أكبر.
- فرص أقل لاختبار سيناريوهات مختلفة تستغرق الاختبارات الأكبر وقتًا أطول، لذا قد يكون اختبار جميع الحالات المحتملة للتطبيق أمرًا غير واقعي.
لمزيد من المعلومات حول إرشادات التصميم، راجِع دليل تصميم التطبيقات.
طُرق الفصل
إذا كان بإمكانك استخراج جزء من دالة أو فئة أو وحدة من الباقي، يصبح اختبارها أسهل وأكثر فعالية. تُعرف هذه الممارسة باسم الفصل، وهي المفهوم الأكثر أهمية في البنية القابلة للاختبار.
تشمل تقنيات الفصل الشائعة ما يلي:
- قسِّم التطبيق إلى طبقات، مثل العرض التقديمي والنطاق والبيانات. يمكنك أيضًا تقسيم التطبيق إلى وحدات، واحدة لكل ميزة.
- تجنَّب إضافة منطق إلى الكيانات التي تتضمّن تبعيات كبيرة، مثل الأنشطة واللقطات. استخدِم هذه الفئات كنقاط دخول إلى إطار العمل، وانقل واجهة المستخدم ومنطق النشاط التجاري إلى مكان آخر، مثل Composable أو ViewModel أو طبقة النطاق.
- تجنَّب التبعيات المباشرة للإطار في الفئات التي تحتوي على منطق النشاط التجاري. على سبيل المثال، لا تستخدِم سياقات Android في ViewModels.
- تسهيل عملية استبدال التبعيات على سبيل المثال، استخدِم الواجهات بدلاً من عمليات التنفيذ المحدّدة. استخدِم تضمين التبعية حتى إذا كنت لا تستخدم إطار عمل لتضمين التبعية.
الخطوات التالية
بعد أن تعرّفت على أهمية الاختبارات ونوعَيها الرئيسيين، يمكنك الاطّلاع على ما يجب اختباره أو التعرّف على استراتيجيات الاختبار.
بدلاً من ذلك، إذا كنت تريد إنشاء اختبارك الأول والتعلم من خلال التجربة، يمكنك الاطّلاع على الدروس التطبيقية حول الاختبار.