פעילויות משמשות כמאגרי נתונים לכל אינטראקציה של משתמש באפליקציה, ולכן חשוב לבדוק את ההתנהגות של הפעילויות באפליקציה במהלך אירועים ברמת המכשיר, כמו האירועים הבאים:
- אפליקציה אחרת, כמו אפליקציית הטלפון של המכשיר, קוטעת את הפעילות של האפליקציה שלכם.
- המערכת מוחקת את הפעילות ויוצרת אותה מחדש.
- המשתמש מציב את הפעילות שלכם בסביבת חלונות חדשה, כמו תמונה בתוך תמונה (PIP) או חלונות מרובים.
בפרט, חשוב לוודא שהפעילות מתנהלת בצורה תקינה בתגובה לאירועים שמתוארים במאמר מחזור החיים של הפעילות.
במדריך הזה מוסבר איך להעריך את היכולת של האפליקציה לשמור על שלמות הנתונים ועל חוויית משתמש טובה, כשפעילויות באפליקציה עוברות בין מצבים שונים במהלך מחזור החיים שלהן.
הגדרת מצב של פעילות
אחד ההיבטים המרכזיים בבדיקת הפעילויות של האפליקציה הוא הצבת הפעילויות של האפליקציה במצבים מסוימים. כדי להגדיר את החלק הזה של הבדיקות, משתמשים במופעים של ActivityScenario, שהוא חלק מהספרייה AndroidX Test. באמצעות המחלקה הזו, אפשר להציב את הפעילות במצבים שמדמים אירועים ברמת המכשיר.
ActivityScenario הוא API חוצה פלטפורמות שאפשר להשתמש בו בבדיקות יחידה מקומיות ובבדיקות אינטגרציה במכשיר. במכשיר אמיתי או וירטואלי, ActivityScenario מספק בטיחות בשרשור, ומסנכרן אירועים בין שרשור המכשיר של הבדיקה לבין השרשור שמריץ את הפעילות שנבדקת.
ה-API מתאים במיוחד להערכת ההתנהגות של פעילות שנמצאת בבדיקה כשהיא מושמדת או נוצרת. בקטע הזה מפורטים התרחישים הנפוצים ביותר שקשורים ל-API הזה.
יצירת פעילות
כדי ליצור את הפעילות שנבדקת, מוסיפים את הקוד שמוצג בקטע הקוד הבא:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { } } }
אחרי שיוצרים את הפעילות, ActivityScenario מעביר את הפעילות למצב RESUMED. המצב הזה מציין שהפעילות שלכם פועלת ושהיא גלויה למשתמשים. במצב הזה, אפשר ליצור אינטראקציה עם רכיבי View הפעילות באמצעות בדיקות ממשק משתמש של Espresso.
Google ממליצה להתקשר אל close בפעילות כשהבדיקה מסתיימת. כך מנקים את המשאבים המשויכים ומשפרים את היציבות של הבדיקות. ActivityScenario מטמיע את Closeable, כך שאפשר להחיל את התוסף use או את try-with-resources בשפת התכנות Java, כדי שהפעילות תיסגר באופן אוטומטי.
לחלופין, אפשר להשתמש ב-ActivityScenarioRule כדי לקרוא אוטומטית ל-ActivityScenario.launch לפני כל בדיקה ול-ActivityScenario.close בביטול הבדיקה. בדוגמה הבאה אפשר לראות איך מגדירים כלל ומקבלים ממנו מופע של תרחיש:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>() @Test fun testEvent() { val scenario = activityScenarioRule.scenario } }
העברת הפעילות למצב חדש
כדי להעביר את הפעילות למצב אחר, כמו CREATED או STARTED, מתקשרים אל moveToState(). הפעולה הזו מדמה מצב שבו הפעילות שלכם מופסקת או מושהית, בהתאמה, כי היא מופרעת על ידי אפליקציה אחרת או פעולת מערכת.
בדוגמה הבאה לשימוש בפקודה moveToState():
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.moveToState(State.CREATED) } } }
קביעת מצב הפעילות הנוכחי
כדי לקבוע את המצב הנוכחי של פעילות שנבדקת, מקבלים את הערך של השדה state באובייקט ActivityScenario. זה שימושי במיוחד לבדיקת הסטטוס של פעילות שנבדקת אם הפעילות מפנה לפעילות אחרת או מסתיימת בעצמה, כמו שמוצג בקטע הקוד הבא:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> startActivity(Intent(activity, MyOtherActivity::class.java)) } val originalActivityState = scenario.state } } }
יצירה מחדש של הפעילות
כשבמכשיר יש מעט משאבים, המערכת עשויה להרוס פעילות, ולכן האפליקציה צריכה ליצור מחדש את הפעילות הזו כשהמשתמש חוזר לאפליקציה. כדי לדמות את התנאים האלה, צריך להתקשר אל recreate():
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.recreate() } } }
המחלקות ActivityScenario שומרות את מצב המופע של הפעילות ואת כל האובייקטים שמסומנים באמצעות @NonConfigurationInstance. האובייקטים האלה נטענים למופע החדש של הפעילות שנבדקת.
אחזור תוצאות הפעילות
כדי לקבל את קוד התוצאה או את הנתונים שמשויכים לפעילות שהסתיימה, צריך לקבל את הערך של השדה result באובייקט ActivityScenario, כמו שמוצג בקטע הקוד הבא:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testResult() { launchActivity<MyActivity>().use { onView(withId(R.id.finish_button)).perform(click()) // Activity under test is now finished. val resultCode = scenario.result.resultCode val resultData = scenario.result.resultData } } }
הפעלת פעולות בפעילות
כל השיטות ב-ActivityScenario הן קריאות חוסמות, ולכן ה-API מחייב אתכם להריץ אותן בשרשור המכשיר.
כדי להפעיל פעולות בפעילות שנבדקת, משתמשים ב-Espresso view matchers כדי ליצור אינטראקציה עם רכיבים בתצוגה:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { onView(withId(R.id.refresh)).perform(click()) } } }
עם זאת, אם אתם צריכים להפעיל שיטה בפעילות עצמה, אתם יכולים לעשות זאת בצורה בטוחה באמצעות הטמעה של ActivityAction:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> activity.handleSwipeToRefresh() } } } }