استخدام اختبار الضعف في Android

عند تصميم استراتيجية الاختبار لعنصر أو نظام، هناك ثلاثة أنواع جوانب الاختبار ذات الصلة:

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

اطّلِع على ما يجب اختباره للتعرّف على كيفية البدء في تحديد استراتيجية الاختبار.

العزلة والتبعيات

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

ومع ذلك، يمكن أن يعتمد الموضوع قيد الاختبار على طُرق أخرى للتمكّن من العمل. بالنسبة مثلاً، قد يعتمد ViewModel على مستودع بيانات لكي يعمل.

عندما تحتاج إلى توفير التبعية لموضوع قيد الاختبار، فإن ممارسة شائعة إنشاء عنصر اختباري (أو كائن اختباري). الزواحف الاختبارية هي كائنات الشكل والعمل كمكونات في التطبيق ولكن يتم إنشاؤها في الاختبار تقديم سلوك أو بيانات محددة. المزايا الرئيسية هي أنها تجعل أسرع وأسهل.

أنواع الاختبارات المزدوجة

وهناك أنواع مختلفة من الاختبارات المزدوجة:

مورِّد مزيف اختبار مزدوج يتضمن علامة "قيد العمل" الفئة، ولكن يتم تنفيذها بطريقة تجعلها جيدة للاختبارات ولكنها غير مناسبة للإنتاج.

مثال: قاعدة بيانات في الذاكرة.

لا تتطلب الصور المزيفة إطار عمل ساخر وهي خفيفة الوزن. هي مفضّلة.

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

مثال: تحقق من أن طريقة في قاعدة البيانات تم استدعاؤها مرة واحدة بالضبط.

Stub اختبار مزدوج يتصرف كيفية برمجته ليعمل ولكن ليس له توقعات حول تفاعلاته. يتم إنشاؤها عادةً باستخدام إطار عمل محاكاة. يُفضّل استخدام المواد المزيّفة بدلاً من التنويهات الموجزة لتبسيطها.
Dummy اختبار مزدوج يتم تمريره ولكن لا يتم استخدامه، مثلاً إذا كنت تحتاج فقط إلى تقديمه كمَعلمة.

مثال: تم تمرير دالة فارغة كرد اتصال للنقرة.

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

مثال يستخدم وهميًا

لنفترض أنك تريد اختبار وحدة ViewModel الذي يعتمد على واجهة. تسمى UserRepository وتعرض اسم المستخدم الأول على واجهة مستخدم. يمكنك إنشاء اختبار مزدوج من خلال تنفيذ الواجهة وإرجاع البيانات البيانات.

object FakeUserRepository : UserRepository {
    fun getUsers() = listOf(UserAlice, UserBob)
}

val const UserAlice = User("Alice")
val const UserBob = User("Bob")

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

يمكن للتبعية المزيفة أن تعرض بيانات معروفة دون الاعتماد على مصادر البيانات البعيدة
الشكل 1: تبعية وهمية في اختبار وحدة

يتأكد الاختبار التالي من أن ViewModel يعرض المستخدم الأول بشكل صحيح. اسم العرض.

@Test
fun viewModelA_loadsUsers_showsFirstUser() {
    // Given a VM using fake data
    val viewModel = ViewModelA(FakeUserRepository) // Kicks off data load on init

    // Verify that the exposed data is correct
    assertEquals(viewModel.firstUserName, UserAlice.name)
}

ومن السهل استبدال UserRepository بعنصر زائف في اختبار الوحدة، لأن يتم إنشاء ViewModel من خلال المختبِر. ومع ذلك، قد يكون من الصعب استبدال العناصر العشوائية في الاختبارات الأكبر.

استبدال المكونات وإدخال التبعية

عندما لا يكون للاختبارات سيطرة على إنشاء الأنظمة قيد الاختبار، فإن استبدال المكونات للمضاعفات الاختبارية يصبح أكثر تعقيدًا ويتطلب بنية تطبيقك لاتباع تصميم قابل للاختبار.

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

الشكل 2: اختبار كبير يشمل معظم التطبيق ويزيّف البيانات عن بُعد

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

الألعاب السلسة

على Android، يمكنك استخدام إطار العمل Robolectric الذي نوعًا خاصًا من الاختبار المزدوج. تتيح لك Robolectric إجراء اختباراتك على أو في محطة العمل أو في بيئة التكامل المستمر. تستخدم JVM العادي، بدون محاكي أو جهاز. وهو يحاكي تضخيم المشاهدات وتحميل الموارد وأجزاء أخرى من إطار عمل Android مع الاختبار تسمى الظلال.

Robolectric هي أداة محاكية لذا يجب عدم استخدامها أو استبدال اختبارات الوحدات البسيطة إجراء اختبار التوافق. أنها توفر السرعة وتقلل التكلفة على النفقات من الدقة المنخفضة في بعض الحالات. أفضل أسلوب لاختبارات واجهة المستخدم هو جعلها متوافقة مع كلّ من اختبارات Robolectric وأداة قياس الأداء وتحديد موعد إجرائها اعتمادًا على الحاجة إلى اختبار الوظائف أو التوافق. كل من قهوة الإسبريسو وإمكانية إجراء اختبارات Compose (إنشاء المحتوى) على Robolectric.