Robolectric هو إطار عمل مفتوح المصدر من صيانة Google يتيح لك إجراء اختبارات في بيئة Android محاكية داخل JVM، بدون أعباء وهجوم المحاكي. وهو متوافق مع جميع إصدارات Android بدءًا من Lollipop (المستوى 21 لواجهة برمجة التطبيقات).
تستخدم العديد من المشاريع الكبيرة Robolectric لزيادة سرعة اختباراتها وموثوقيتها وخفض النفقات المرتبطة بإجراء الاختبارات على الأجهزة الحقيقية أو محاكيات التطبيقات. ويشمل ذلك معظم تطبيقات Google التي تعتمد بشكل كبير على Robolectric.
لا يشكّل Robolectric بديلاً كاملاً للمحاكي لأنّه لا يسمح باستخدام جميع الميزات وواجهات برمجة التطبيقات. على سبيل المثال، لا يتضمّن Robolectric شاشة مثل المحاكي، وبعض واجهات برمجة التطبيقات متوافقة جزئيًا فقط. ومع ذلك، يحاكي هذا الجهاز أجزاء كافية من Android لإجراء اختبارات الوحدات ومعظم اختبارات واجهة المستخدم بطريقة موثوقة.
استراتيجيات الاختبار
هناك نوعان من استراتيجيات الاختبار التي يمكنك اتّباعها باستخدام Robolectric: اختبار الوحدات واختبار واجهة المستخدم.
اختبار الوحدة
تم تصميم Robolectric كطريقة لتفعيل "اختبار الوحدة" في تطبيقات Android. على سبيل المثال، يمكنك محاكاة إطلاق نشاط واختبار المنطق داخله، مع استدعاء جميع طرق دورة الحياة.
يمكنك أيضًا استخدام العناصر المزيّفة في Robolectric (المعروفة باسم "الظلال") كعناصر تابعة لاختبارات الوحدت. على سبيل المثال، إذا كانت صفتك تستخدم حِزمة أو كنت بحاجة إلى إنشاء اتصال بالبلوتوث بشكل زائف.
بشكل عام، إذا نفّذت بنية قابلة للاختبار، لن تحتاج إلى استخدام Robolectric لاختبار الوحدة لأنّه من المفترض أن يكون الرمز قابلاً للاختبار بشكل منفصل، بدون أي تبعيات على إطار عمل Android.
اختبار واجهة المستخدم
يمكن أن يُجري Robolectric أيضًا اختبارات واجهة المستخدم، مثل اختبارات Espresso أو Compose. يمكنك
تحويل اختبار تم قياس حالته إلى Robolectric من خلال نقله إلى test
مجموعة المصادر وإعداد التبعيات في Robolectric.
android {
testOptions {
unitTests {
isIncludeAndroidResources = true
}
}
}
dependencies {
testImplementation("junit:junit:4.13.2")
testImplementation("org.robolectric:robolectric:4.13")
}
يتم تشغيل أي اختبار واجهة مستخدم متوفّر في مجموعة مصادر test
باستخدام Robolectric.
import androidx.test.espresso.Espresso.onView
@RunWith(AndroidJUnit4::class)
class AddContactActivityTest {
@Test
fun inputTextShouldBeRetainedAfterActivityRecreation() {
// GIVEN
val contactName = "Test User"
val scenario = ActivityScenario.launchActivity<AddContactActivity>()
// WHEN
// Enter contact name
onView(withId(R.id.contact_name_text))
.perform(typeText(contactName))
// Destroy and recreate Activity
scenario.recreate()
// THEN
// Check contact name was preserved.
onView(withId(R.id.contact_name_text))
.check(matches(withText(contactName)))
}
}
ولا تتفاعل معظم اختبارات واجهة المستخدم مع إطار العمل ويمكنك إجراؤها على Robolectric. يمكنك إجراء اختبارات السلوك على Robolectric لأنّه يقدّم الدقّة المطلوبة بدرجة كافية. على سبيل المثال، عندما يتحقق اختبار Compose من أنّه تغير واجهة المستخدم بعد النقر على زر.
يمكنك إجراء اختبارات واجهة مستخدم أخرى باستخدام Robolectric، مثل اختبارات لقطات الشاشة. ومع ذلك، تكون الدقّة أقل لأنّ الأجهزة المختلفة تعرض المحتوى على الشاشة بشكل مختلف قليلاً.
عليك تحديد ما إذا كان استخدام Robolectric مناسبًا لكل حالة استخدام، ولكن إليك بعض الاقتراحات:
- استخدِم Robolectric لاختبار سلوك واجهة المستخدم المعزولة على المكوّنات أو الميزات أو التطبيقات. بشكل عام، تتحقّق هذه الاختبارات من إدارة الحالة و سلوك واجهات المستخدم ولا تتفاعل مع التبعيات الخارجية.
- استخدِم Robolectric لالتقاط لقطات شاشة عندما لا تكون دقة البكسل ضرورية. على سبيل المثال، لاختبار كيفية تفاعل مكوّن مع أحجام خطوط أو مظاهر مختلفة.
ملاحظة: يمكن لروبوليتريك أخذ لقطات شاشة بشكلٍ أصلي، ولكنك تحتاج إلى مكتبة تابعة لجهة خارجية لإجراء اختبار لقطات الشاشة باستخدامها.
Robolectric في مقابل اختبارات الأجهزة
باختصار، توفّر Robolectric دقة كافية لإجراء معظم اختبارات واجهة المستخدم، إلا أنّ بعض الحالات ستظل تتطلب اختبارات للأجهزة، مثل تلك المتعلقة بواجهة مستخدم النظام مثل الشاشة من حافة إلى الحافة أو "نافذة ضمن النافذة"، أو عند الاعتماد على ميزات غير متوافقة، مثل WebView
.