פיתוח בדיקות UI לאפליקציות אנדרואיד (Espresso)
כתבת מסך התחברות ב-Compose, הגדרת Hilt, הוספת Retrofit. אתה מריץ את הבדיקה — היא נכשלת. למה? בדיקות UI באנדרואיד הן לעיתים קרובות לא יציבות — הסיבה השורשית היא כמעט תמיד התעלמות מ-IdlingResource. מפתחים מכניסים Thread.sleep(2000) ומקווים שזה יעבור — זו דרך לכאוס. ללא IdlingResource מוגדר כראוי, היציבות רק לעיתים רחוקות עולה על 60%. ערכת בדיקות של 100+ בדיקות דורשת 2–3 שעות לריצה, חצי נכשלות בגלל תזמון.
אנו מציעים פיתוח בדיקות UI מסוג Espresso במפתח מלא. אנו מתכננים ארכיטקטורה עם דפוס Robot, מגדירים IdlingResource לכל הפעולות האסינכרוניות, ומשתלבים עם Firebase Test Lab. תוך 3–5 ימים אתה מקבל סט יציב של זרימות משתמש קריטיות (התחברות, תשלום, UX ליבה). אחד הפרויקטים שלנו — אפליקציית בנקאות אינטרנטית עם 1,200 בדיקות — השיג יציבות של 98.5% לאחר כוונון IdlingResource.
גוגל ממליצה רשמית להשתמש ב-IdlingResource כדי לסנכרן בדיקות עם משימות רקע — זה הבסיס לבדיקות אוטומטיות יציבות.
יסודות וניואנסים קריטיים
מבנה בדיקת Espresso בסיסי: onView(matcher).perform(action).check(assertion).
@Test
fun loginWithValidCredentials_navigatesToHome() {
onView(withId(R.id.emailInput))
.perform(typeText("[email protected]"), closeSoftKeyboard())
onView(withId(R.id.passwordInput))
.perform(typeText("password123"), closeSoftKeyboard())
onView(withId(R.id.loginButton))
.perform(click())
onView(withId(R.id.homeTitle))
.check(matches(isDisplayed()))
}הגורם השכיח ביותר לבדיקות לא יציבות הוא IdlingResource. אם האפליקציה מבצעת בקשה אסינכרונית (Retrofit, Coroutine), Espresso לא מודע לכך ומנסה למצוא את האלמנט הבא לפני שהפעולה מסתיימת. הפתרון — רישום IdlingResource.
// Для OkHttp/Retrofit используйте OkHttpIdlingResource
val idlingResource = OkHttpIdlingResource.create("okhttp", okHttpClient)
IdlingRegistry.getInstance().register(idlingResource)
// Для корутин используйте EspressoIdlingResource
IdlingRegistry.getInstance().register(EspressoIdlingResource.getIdlingResource())Espresso רץ פי 2–3 מהר יותר מ-UIAutomator כי הוא נמנע מ-sleep.
למה בדיקות Espresso נכשלות?
מלבד IdlingResource, בעיה נפוצה היא תנאי מרוץ בעבודה עם RecyclerView או ריבוי תהליכונים. השתמש ב-IdlingResource לפעולות אסינכרוניות וב-CountingIdlingResource למשימות רקע. מניסיוננו, לאחר יישום IdlingResource, יציבות הבדיקות קופצת מ-60% ל-95%.
| בעיה | פתרון |
|---|---|
| בקשות אסינכרוניות (Retrofit, Coroutine) | OkHttpIdlingResource / EspressoIdlingResource |
| טעינת תמונות (Glide, Coil) | GlideIdlingResource |
| אנימציות (Transition, Lottie) | השבתת אנימציות בבדיקות |
| RecyclerView עם פגינציה | CountingIdlingResource |
בדיקות UI ב-Jetpack Compose
אם הפרויקט משתמש ב-Compose, גישת Espresso מוחלפת ב-ComposeTestRule:
@get:Rule
val composeTestRule = createAndroidComposeRule<MainActivity>()
@Test
fun loginScreen_showsErrorOnInvalidEmail() {
composeTestRule.onNodeWithTag("emailInput")
.performTextInput("invalid-email")
composeTestRule.onNodeWithTag("loginButton")
.performClick()
composeTestRule.onNodeWithText("Неверный формат email")
.assertIsDisplayed()
}testTag ב-Compose — המקבילה ל-accessibilityIdentifier ב-iOS. אנו תמיד מקצים תגיות לכל האלמנטים הניתנים לבדיקה באמצעות @Test fun loginWithValidCredentials_navigatesToHome() { onView(withId(R.id.emailInput)) .perform(typeText("[email protected]"), closeSoftKeyboard()) onView(withId(R.id.passwordInput)) .perform(typeText("password123"), closeSoftKeyboard()) onView(withId(R.id.loginButton)) .perform(click()) onView(withId(R.id.homeTitle)) .check(matches(isDisplayed())) } .
איך לזרז כתיבת בדיקות?
אנו משתמשים בדפוס Robot — המקבילה ב-Compose ל-Page Object. זה הופך את הבדיקות לקריאות כמו תרחישים ומפשט רפקטורינג. השוואה:
| קריטריון | דפוס Robot | Page Object |
|---|---|---|
| תחביר | שרשורי קריאות (Builder) | מתודות ללא החזרת אובייקט |
| קריאות | גבוהה, דומה לשלבי תרחיש בדיקה | בינונית, דורש מבנה נוסף |
| שימוש חוזר | דרך קומפוזיציית רובוטים | דרך ירושת מחלקות עמוד |
| תמיכה ב-Compose | טבעי, ללא עטיפות נוספות | דורש התאמה |
דפוס Robot מתאים יותר לפרויקטים של Compose. דוגמה:
class LoginRobot(private val composeTestRule: AndroidComposeTestRule<*, *>) {
fun enterEmail(email: String) = apply {
composeTestRule.onNodeWithTag("emailInput").performTextInput(email)
}
fun enterPassword(password: String) = apply {
composeTestRule.onNodeWithTag("passwordInput").performTextInput(password)
}
fun clickLogin() = apply {
composeTestRule.onNodeWithTag("loginButton").performClick()
}
fun assertHomeVisible() {
composeTestRule.onNodeWithTag("homeScreen").assertIsDisplayed()
}
}
// Тест читается как сценарий
@Test
fun validLogin_showsHome() {
LoginRobot(composeTestRule)
.enterEmail("[email protected]")
.enterPassword("pass123")
.clickLogin()
.assertHomeVisible()
} Hilt ו-DI בבדיקות אינסטרומנטליות
אם הפרויקט משתמש ב-Hilt, הבדיקות דורשות HiltAndroidRule. ההערה @BindValue מאפשרת להחליף מאגר אמיתי ב-fake ללא שינוי קוד הייצור — הבדיקה לא תלויה ברשת או במסד נתונים.
איך לכתוב בדיקת Espresso יציבה ב-5 שלבים
- הגדר את התרחיש וזהה פעולות אסינכרוניות.
- רשום IdlingResource לכל פעולה.
- השתמש בדפוס Robot למבנה.
- הרץ את הבדיקה מקומית, ודא יציבות.
- שלב עם CI ו-Firebase Test Lab.
CI: Firebase Test Lab
אמולטור מקומי מספיק לפיתוח, אבל לפני שחרור — Firebase Test Lab עם מכשירים אמיתיים. דוגמת workflow (GitHub Actions):
---
- name: Run Espresso tests on Firebase Test Lab
run: |
gcloud firebase test android run \
--type instrumentation \
--app app/build/outputs/apk/debug/app-debug.apk \
--test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
--device model=Pixel8,version=34 \
--device model=GalaxyS23,version=33
תוצאות — Logcat, צילומי מסך בכשלון, וידאו של הריצה — נשמרות ב-Google Cloud Storage. הגדרת CI כלולה בהיקף העבודה.
מה כלול בפיתוח בדיקות UI ב-Espresso
- עיצוב ארכיטקטורת בדיקות (בחירת דפוס, הגדרת IdlingResource)
- כתיבת זרימות משתמש קריטיות (התחברות, תשלום, UX ליבה) עם דפוס Robot
- אינטגרציית CI/CD (GitHub Actions, Firebase Test Lab)
- תיעוד להרצה ותחזוקת בדיקות
- הדרכת צוות (סדנה של 1–2 שעות)
פיתחנו בדיקות UI ל-15+ אפליקציות אנדרואיד, יציבות ממוצעת — 97%, הפרויקט הגדול ביותר — 1,200 בדיקות. זמן ריצה ממוצע ל-100 בדיקות — 15 דקות לעומת שעתיים ללא אופטימיזציה.
לוח זמנים: מ-3 עד 10 ימים תלוי במורכבות האפליקציה. התמחור אישי. אם אתה צריך עזרה ביישום — צור קשר, נערוך ביקורת ונציע פתרון. הזמן פיתוח ערכת בדיקות — אנו מבטיחים יציבות >95% וחודש תמיכה.
רשימת בדיקה לבדיקות UI יציבות
- תמיד רשום IdlingResource לכל תהליכי הרקע.
- לעולם אל תשתמש ב-Thread.sleep() — השתמש בהמתנה מפורשת דרך IdlingResource.
- ודא שאנימציות מושבתות בפרופיל הבדיקה של המכשיר.
- הרץ בדיקות על מכשירים אמיתיים דרך Firebase Test Lab.
- נקה מצב בין בדיקות (clearState ב-@Before).
- השתמש בדפוס Robot לקריאות ושימוש חוזר.







