אסטרטגיות של Robolectric

Robolectric היא מסגרת קוד פתוח בניהול Google שמאפשרת להריץ בדיקות בסביבת Android מדומה בתוך JVM, בלי העלות הנוספת והבלתי עקבית של אמולטור. הוא תומך בכל הגרסאות של Android מאז Lollipop (רמת API 21).

בפרויקטים גדולים רבים משתמשים ב-Robolectric כדי להגביר את המהירות והאמינות של הבדיקות ולצמצם את ההוצאות שמשויכות להרצת בדיקות במכשירים אמיתיים או במהדמנים. הדבר כולל את רוב האפליקציות של Google, שמסתמכות במידה רבה על Robolectric.

Robolectric הוא לא תחליף מלא למהדר, כי הוא לא תומך בכל התכונות ובכל ממשקי ה-API. לדוגמה, ב-Robolectric אין מסך כמו שיש באמולטור, וחלק מממשקי ה-API נתמכים רק באופן חלקי. עם זאת, הוא מעתיק מספיק חלקים של Android כדי להריץ בדיקות יחידה ואת רוב בדיקות ממשק המשתמש בצורה מהימנה.

אסטרטגיות בדיקה

יש שני סוגים של אסטרטגיות בדיקה שאפשר להשתמש בהן ב-Robolectric: בדיקת יחידה ובדיקת ממשק משתמש.

בדיקות יחידה

Robolectric תוכנן לאפשר הפעלה של 'בדיקת יחידה' באפליקציות ל-Android. לדוגמה, אפשר לדמות את ההפעלה של פעילות ולבדוק את הלוגיקה שבתוכה, על ידי קריאה לכל השיטות של מחזור החיים.

אפשר גם להשתמש ב-Fakes של Robolectric (שנקראים 'צללים') כיחסי תלות לבדיקות יחידה. לדוגמה, אם הכיתה משתמשת ב-Bundle או אם אתם צריכים לזייף חיבור Bluetooth.

באופן כללי, אם מטמיעים ארכיטקטורה שניתנת לבדיקה, לא צריך להשתמש ב-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.