משאב ביטול עסקה מייצג פעולה אסינכרונית שהתוצאות שלה משפיעות על הפעולות הבאות בבדיקת ממשק משתמש. באמצעות רישום משאבים במצב 'לא פעיל' אצל Espresso, תוכלו לאמת את הפעולות האסינכרוניות האלה בצורה אמינה יותר לבדוק את האפליקציה.
לזהות מתי יש צורך במשאבים במצב 'לא פעיל'
אספרסו מספק ערכה מתוחכמת
יכולות סנכרון. הזה
של ה-framework, חל רק על פעולות
הודעות בMessageQueue
, כמו תת-מחלקה של
View
מסמן את התוכן שלו על המסך.
כי Espresso לא מודעת לפעולות אסינכרוניות אחרות, כולל אלה שפועלים על שרשור ברקע, Espresso לא יכולה לספק את הסנכרון אחריות במצבים האלה. כדי להציג את Espresso באפליקציה של פעולות ממושכות, עליכם לרשום כל אחת מהן כמשאב ללא פעילות.
אם אתם לא משתמשים במשאבים של ביטול פעולה בזמן בדיקת התוצאות של האפליקציה בעבודה אסינכרונית, ייתכן שתצטרכו להשתמש באחת ביצוע "פתרונות לא טובים" כדי לשפר את הבדיקות אמינות:
- המערכת מוסיפה שיחות ל-
Thread.sleep()
. אחרי ש להוסיף עיכובים מלאכותיים לבדיקות, חבילת הבדיקות לוקחת זמן רב יותר לסיום הביצוע, והבדיקות עדיין עשויות להיכשל לפעמים כשמריצים אותן של מכשירים איטיים יותר. בנוסף, העיכובים האלה לא מתפתחים כמו שצריך, כי האפליקציה עשויה להיות צורך לבצע עבודה אסינכרונית שגוזלת זמן רב יותר בגרסה עתידית. - הטמעה של רכיבי wrapper של ניסיונות חוזרים, שמשתמשים בלולאה כדי לבדוק שוב ושוב אם האפליקציה שלך עדיין מבצעת עבודה אסינכרונית עד שהזמן הקצוב לתפוגה יסתיים. גם אם ציינתם בבדיקות שלכם את המספר המקסימלי של הניסיונות החוזרים, כל הרצה מחדש צורכת במשאבי המערכת, במיוחד המעבד (CPU).
- באמצעות מופעים של
CountDownLatch
, לאפשר לשרשור אחד או יותר להמתין עד שמספר ספציפי של פעולות שבוצעו בשרשור אחר. באובייקטים האלה צריך לציין משך זמן קצוב לתפוגה; אחרת, ייתכן שהאפליקציה תיחסם ללא הגבלת זמן. הנעילה גם להוסיף לקוד מורכבות מיותרת, מה שמקשה על התחזוקה שלו.
Espresso מאפשר להסיר מהבדיקות את הדרכים הלא אמינות האלה במקום זאת, לרשום את העבודה האסינכרונית של האפליקציה כמשאבים שאינם פעילים.
תרחישים נפוצים לדוגמה
כשמבצעים פעולות שדומות לדוגמאות הבאות בבדיקות, כדאי להשתמש במשאב מסוג 'לא פעיל':
- טעינת נתונים מהאינטרנט או ממקור נתונים מקומי.
- יצירת חיבורים עם מסדי נתונים וקריאות חוזרות (callback).
- ניהול שירותים, באמצעות שירות מערכת או מכונה של
IntentService
. - ביצוע לוגיקה עסקית מורכבת, כמו טרנספורמציות של מפת סיביות (bitmap).
חשוב במיוחד לרשום משאבים במצב 'לא פעיל' כשהפעולות האלה לעדכן ממשק משתמש שהבדיקות שלכם מאמתות לאחר מכן.
דוגמאות להטמעות של משאבים במצב 'לא פעיל'
ברשימה הבאה מתוארות מספר הטמעות של דוגמאות למשאבים שאינם פעילים שאפשר לשלב באפליקציה:
CountingIdlingResource
- שומר על מונה של משימות פעילות. כשהמונה הוא אפס,
משאב נחשב ללא פעיל. הפונקציונליות הזאת דומה מאוד
Semaphore
ברוב המקרים, ההטמעה מספיקים לניהול העבודה האסינכרונית של האפליקציה במהלך הבדיקה. UriIdlingResource
- דומה ל-
CountingIdlingResource
, אבל המונה צריך להיות אפס לפרק זמן ספציפי לפני משאב נחשב ללא פעיל. תקופת ההמתנה הנוספת הזו נמשכת רצף בקשות רשת, כאשר אפליקציה בשרשור עשויה ליצור מיד לאחר קבלת תשובה לבקשה קודמת. IdlingThreadPoolExecutor
- הטמעה מותאמת אישית של
ThreadPoolExecutor
שעוקב אחרי המספר הכולל של המשימות הפעילות בשרשור שנוצר. בריכות. בכיתה הזו נעשה שימושCountingIdlingResource
עד לשמור על מספר המשימות הפעילות. IdlingScheduledThreadPoolExecutor
- יישום מותאם אישית של
ScheduledThreadPoolExecutor
. היא מספקת ויכולותIdlingThreadPoolExecutor
כיתה, אבל הוא יכול גם לעקוב אחר משימות שתוזמנו לעתיד או מתוזמנים לפעול מעת לעת.
יצירת משאב משלכם במצב 'לא פעיל'
בזמן השימוש במשאבים זמניים בבדיקות של האפליקציה, יכול להיות שיהיה צורך לספק ניהול או רישום ביומן של משאבים מותאמים אישית. במקרים כאלה, ההטמעות שמפורט בקטע הקודם, לא מספיק. במקרה כזה, אפשר להרחיב אחד מההטמעות של המשאבים הזמניים האלה או ליצור משאבים משלכם.
אם אתם מטמיעים פונקציונליות של משאבים זמניים ללא פעילות, הקפידו לפעול לפי ההנחיות הבאות במיוחד שחשוב לזכור, בייחוד הראשונה:
- הפעלת מעברים למצב לא פעיל מחוץ לבדיקות שאינן פעילות.
- כשהאפליקציה הופכת ללא פעילות, אפשר להתקשר
onTransitionToIdle()
מחוץ לכל יישום שלisIdleNow()
. כך, 'אספרסו' לא מבצע בדיקה נוספת, מיותרת, כדי לקבוע אם המשאב הלא פעיל אינו פעיל.
קטע הקוד הבא ממחיש את ההמלצה הזו:
Kotlin
fun isIdle() { // DON'T call callback.onTransitionToIdle() here! } fun backgroundWorkDone() { // Background work finished. callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle. // Don't do any post-processing work beyond this point. Espresso now // considers your app to be idle and moves on to the next test action. }
Java
public void isIdle() { // DON'T call callback.onTransitionToIdle() here! } public void backgroundWorkDone() { // Background work finished. callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle. // Don't do any post-processing work beyond this point. Espresso now // considers your app to be idle and moves on to the next test action. }
- לרשום משאבים במצב 'לא פעיל' לפני שיהיה בהם צורך.
יתרונות הסנכרון שקשורים למשאבים שפועלים באופן לא פעיל נכנסים לתוקף רק אחרי ההפעלה הראשונה של Espresso של המשאב
isIdleNow()
.הרשימה הבאה מציגה כמה דוגמאות לנכס הזה:
- אם רושמים משאב לא פעיל בשיטה שמסומנת בהערה עם
@Before
, המשאב הלא פעיל נכנס לתוקף בשורה הראשונה של כל בדיקה. - אם רושמים משאב לא פעיל בבדיקה, המשאב 'ביטול פעולה' תיכנס לתוקף במהלך הפעולה הבאה המבוססת על אספרסו. ההתנהגות הזו עדיין גם אם הפעולה הבאה היא באותה מבחן כמו הטענה רושם את המשאב שאינו פעיל.
- אם רושמים משאב לא פעיל בשיטה שמסומנת בהערה עם
- ביטול הרישום של משאבים במצב 'ביטול פעולה' בסיום השימוש
כדי לחסוך במשאבי מערכת, צריך לבטל את הרישום של משאבים שאינם פעילים בהקדם כי אתם כבר לא צריכים אותם. לדוגמה, אם רושמים משאב במצב 'לא פעיל' בשיטה שמסומנת בהערה עם
@Before
, כדאי לבטל את הרישום של המשאב בשיטה המתאימה שמצוינת בהערה@After
.- יש להשתמש במרשם הודעות (idling) כדי לרשום ולבטל רישום של משאבים בסטטוס 'לא פעיל'.
באמצעות המאגר הזה למשאבים שנמצאים במצב 'לא פעיל' של האפליקציה, אפשר לרשום וגם לבטל רישום של משאבים בסטטוס 'לא פעיל' שוב ושוב לפי הצורך, ועדיין לשמור על עקביות או התנהגות המשתמשים.
- חשוב לשמור על מצב אפליקציה פשוט בלבד בתוך משאבים של ביטול פעילות.
לדוגמה, אתם לא צריכים לאפשר את מכילים הפניות ל-
View
אובייקטים.
רישום משאבים במצב 'לא פעיל'
Espresso מספק מחלקה של קונטיינרים שבה אפשר להציב את קובץ העזר של האפליקציה
המשאבים. הכיתה הזו, שנקראת
IdlingRegistry
, הוא
ארטיפקט עצמאי שמספק תקורה מינימלית לאפליקציה. הכיתה
מאפשר לך גם לבצע את השלבים הבאים כדי לשפר את היישום של האפליקציה
תחזוקה:
- יצירת הפניה אל
IdlingRegistry
, במקום למשאבים שנמצאים במצב 'לא פעיל' שהוא מכיל, בבדיקות של האפליקציה. - לשמור על ההבדלים באוסף של משאבים זמניים שמשמשים אתכם כל וריאנט של build.
- יש להגדיר משאבים לא פעילים בשירותי האפליקציה במקום בממשק המשתמש הרכיבים שמפנים לשירותים האלה.
שילוב משאבים במצב 'לא פעיל' באפליקציה
אפשר להוסיף לאפליקציה משאבים במצב 'לא פעיל' בכמה דרכים שונות, באופן ספציפי, היא שומרת על כמות גדולה של נתונים באפליקציה, אבל עדיין מאפשרת כדי לציין פעולה מסוימת שמייצג משאב ביטול פעולה נתון.
גישה מומלצת
כשמוסיפים לאפליקציה משאבים במצב 'לא פעיל', מומלץ מאוד להציב את המתנה של לוגיקת משאבים באפליקציה עצמה וביצוע רישום בלבד, ביטול הרישום בבדיקות שלך.
למרות שיצרת מצב חריג של שימוש בממשק לבדיקה בלבד, את קוד הייצור על ידי יישום הגישה הזו, אפשר לעטוף משאבים במצב 'לא פעיל' שכבר יש לך, תוך שמירה על גודל ה-APK וספירת השיטות של האפליקציה.
גישות חלופיות
אם אתם מעדיפים שלא להגדיר לוגיקת משאבים של ביטול פעולה בסביבת הייצור של האפליקציה יש כמה אסטרטגיות שילוב מעשיות נוספות:
- יצירת וריאציות build, כמו Gradle מוצר טעמים, ומשתמשים במשאבים של מצב 'ביטול פעולה' רק ב-build של ניפוי הבאגים של האפליקציה.
- שימוש במסגרת החדרת תלות כמו Dagger כדי להחדיר את חוסר הפעילות של האפליקציה בבדיקות שלכם, אתם יכולים לראות את תרשים התלות של המשאבים. אם משתמשים ב-Dagger 2, ההזרקה עצמה צריכה להגיע מרכיב משנה.
מטמיעים משאב לא פעיל בבדיקות של האפליקציה וחושפים את החלק של הטמעת האפליקציה שצריך לסנכרן בדיקות.
זהירות: אף על פי שההחלטה הזו לגבי העיצוב, נראה יוצרת הפניה עצמאית לסידור משאבים, גם אנקפסולציה בכל האפליקציות חוץ מהפשוטה ביותר.
מקורות מידע נוספים
למידע נוסף על השימוש ב-Espresso בבדיקות Android, אפשר לעיין ב במקורות המידע הבאים.
דוגמיות
- IdlingResourceSample: סנכרון עם משימות ברקע.