أساسيات اختبار تطبيقات Android

تحدد هذه الصفحة المبادئ الأساسية لاختبار تطبيقات Android، بما في ذلك أفضل الممارسات المركزية وفوائدها.

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

تعد مرحلة الاختبار جزءًا لا يتجزأ من عملية تطوير التطبيقات. ويمكنك التحقّق من سلامة تطبيقك وفعالية وظائفه وسهولة استخدامه قبل إصداره للعلن من خلال إجراء سلسلة من الاختبارات على التطبيق بشكل منتظم.

يمكنك اختبار تطبيقك يدويًا من خلال التنقّل فيه. يمكنك استخدام أجهزة ومحاكيات مختلفة، وتغيير لغة النظام، ومحاولة إنشاء كل خطأ يرتكبه المستخدم أو التنقّل في كل مسار للمستخدِم.

ومع ذلك، لا يمكن توسيع نطاق الاختبار اليدوي بشكلٍ جيد، وقد يكون من السهل التغافل عن التراجع في أداء تطبيقك. يتضمن الاختبار التلقائي استخدام الأدوات التي تجري الاختبارات نيابةً عنك، وهي أسرع وأكثر تكرارًا، وتمنحك بوجه عام ملاحظات قابلة للتنفيذ حول تطبيقك في وقت مبكر من عملية التطوير.

أنواع الاختبارات في Android

التطبيقات المتوافقة مع الأجهزة الجوّالة معقّدة ويجب أن تعمل بشكل جيد في العديد من البيئات. ولذلك، هناك العديد من أنواع الاختبارات.

الموضوع

على سبيل المثال، هناك أنواع مختلفة من الاختبارات حسب المادة:

  • الاختبار الوظيفي: هل ينفّذ تطبيقي ما من المفترض أن يفعله؟
  • اختبار الأداء: هل يتم إجراء الاختبار بسرعة وكفاءة؟
  • اختبار تسهيل الاستخدام: هل يعمل التطبيق بشكل جيد مع خدمات تسهيل الاستخدام؟
  • اختبار التوافق: هل يعمل التطبيق بشكل جيد على كل الأجهزة ومستويات واجهة برمجة التطبيقات؟

المجال

تختلف الاختبارات أيضًا حسب الحجم أو درجة العزلة:

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

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

الاختبارات الآلية مقارنةً بالاختبارات المحلية

يمكنك إجراء الاختبارات على جهاز Android أو على جهاز كمبيوتر آخر:

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

لا تكون جميع اختبارات الوحدات محلية، ولا يتم تنفيذ جميع الاختبارات الشاملة على جهاز. على سبيل المثال:

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

أمثلة

توضِّح المقتطفات التالية كيفية التفاعل مع واجهة المستخدم في اختبار واجهة مستخدِم تمّ تجهيزه بالأدوات الذي ينقر على عنصر ويتأكّد من أنّه يتم عرض عنصر آخر.

إسبريسو

// 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.
  • اجعل التبعيات سهلة للاستبدال. على سبيل المثال، استخدم الواجهات بدلاً من عمليات التنفيذ الملموسة. استخدِم حقن التبعية حتى إذا كنت لا تستخدم إطار عمل حقن التبعية.

الخطوات التالية

بعد أن تعرّفت على سبب إجراء الاختبارات والنوعَين الرئيسيَين من الاختبارات، يمكنك قراءة العناصر التي يجب اختبارها أو الاطّلاع على استراتيجيات الاختبار.

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