UI Automator הוא מסגרת לבדיקת ממשק משתמש שמתאימה לממשק משתמש פונקציונלי בכל האפליקציות
בדיקות באפליקציות במערכת ובאפליקציות מותקנות. ממשקי API Automator API מאפשרים לך ליצור אינטראקציה
עם רכיבים גלויים במכשיר, בלי קשר למיקום Activity
להתמקד כך שניתן יהיה לבצע פעולות כמו פתיחת תפריט ההגדרות
או במרכז האפליקציות במכשיר בדיקה. הבדיקה שלך יכולה לחפש רכיב בממשק המשתמש על ידי
באמצעות תיאורים נוחים, כמו הטקסט שמוצג ברכיב
לתיאור התוכן.
מסגרת הבדיקה של UI Automator היא API שמבוססת על אינסטרומנטציה והיא פועלת
עם לוח הבקרה AndroidJUnitRunner
. מתאים מאוד לכתיבה
בדיקות אוטומטיות בסגנון תיבה אטומה, שבהן קוד הבדיקה לא מסתמך על
פרטי ההטמעה של אפליקציית היעד.
התכונות העיקריות של מסגרת הבדיקה של UI Automator כוללות את אלה:
- ממשק API לאחזור פרטי מצב ולביצוע פעולות על היעד במכשיר. מידע נוסף זמין במאמר גישה למצב המכשיר.
- ממשקי API שתומכים בבדיקת ממשק משתמש בין אפליקציות. למידע נוסף, ראה ממשק משתמש Automator APIs.
גישה למצב המכשיר
מסגרת הבדיקה של UI Automator מספקת גישה למחלקה UiDevice
ולבצע פעולות במכשיר שבו אפליקציית היעד פועלת. אפשר
להפעיל את ה-methods של המכשיר כדי לגשת למאפייני המכשיר, כמו כיוון נוכחי או
גודל התצוגה. הכיתה UiDevice
מאפשרת גם לבצע את הפעולות הבאות
פעולות:
- שינוי הסיבוב של המכשיר.
- מקישים על מקשי חומרה, למשל "הגברת עוצמת הקול".
- לוחצים על הלחצנים 'הקודם', 'דף הבית' או 'תפריט'.
- פותחים את לוח ההתראות.
- מצלמים צילום מסך של החלון הנוכחי.
לדוגמה, כדי לדמות לחיצה על לחצן דף הבית, קוראים לפונקציה UiDevice.pressHome()
.
ממשקי API Automator API
ממשקי ה-API של UI Automator מאפשרים לכם לכתוב בדיקות מחמירות בלי שתצטרכו לדעת פרטי ההטמעה של האפליקציה המטורגטת. אפשר להשתמש את ממשקי ה-API האלה כדי לתעד ולשנות רכיבי ממשק משתמש באפליקציות מרובות:
UiObject2
: מייצג רכיב בממשק המשתמש שגלוי במכשיר.BySelector
: ציון הקריטריונים להתאמה של רכיבי ממשק משתמש.By
: הגדרה שלBySelector
באופן תמציתי.Configurator
: מאפשרת להגדיר פרמטרים מרכזיים להרצת בדיקות אוטומציה של ממשק המשתמש.
לדוגמה, הקוד הבא מראה איך לכתוב סקריפט לבדיקה פותחת אפליקציית Gmail במכשיר:
Kotlin
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) device.pressHome() val gmail: UiObject2 = device.findObject(By.text("Gmail")) // Perform a click and wait until the app is opened. val opened: Boolean = gmail.clickAndWait(Until.newWindow(), 3000) assertThat(opened).isTrue()
Java
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.pressHome(); UiObject2 gmail = device.findObject(By.text("Gmail")); // Perform a click and wait until the app is opened. Boolean opened = gmail.clickAndWait(Until.newWindow(), 3000); assertTrue(opened);
הגדרת אוטומציה של ממשק המשתמש
לפני שיוצרים בדיקת ממשק משתמש באמצעות אוטומציה של ממשק המשתמש, חשוב להגדיר את הבדיקה מיקום של קוד מקור ויחסי תלות של פרויקטים, כפי שמתואר במאמר הגדרת פרויקט לבדיקת AndroidX.
בקובץ build.gradle
של מודול האפליקציה ל-Android, צריך להגדיר תלות
הפניה לספריית הכלים האוטומטיים של ממשק המשתמש:
Kotlin
dependencies {
...
androidTestImplementation('androidx.test.uiautomator:uiautomator:2.3.0-alpha03')
}
Groovy
dependencies {
...
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.3.0-alpha03'
}
כדי לבצע אופטימיזציה של הבדיקה באמצעות האוטומציה של ממשק המשתמש, תחילה עליך לבדוק את אפליקציית היעד רכיבי ממשק המשתמש ולוודא שהם נגישים. הטיפים האלה לאופטימיזציה שמתוארים בשני הקטעים הבאים.
בדיקת ממשק המשתמש במכשיר
לפני תכנון הבדיקה, יש לבדוק את רכיבי ממשק המשתמש הגלויים
במכשיר. כדי להבטיח שהבדיקות של ממשק המשתמש האוטומטי יוכלו לגשת לרכיבים האלה,
לבדוק שלרכיבים האלה יש תוויות טקסט גלויות,
android:contentDescription
, או את שניהם.
הכלי uiautomatorviewer
מספק ממשק חזותי נוח לבדיקה
היררכיית הפריסה וצפייה במאפיינים של רכיבי ממשק המשתמש הגלויים
בחזית המכשיר. המידע הזה מאפשר לכם ליצור
בדיקות פרטניות באמצעות אוטומציה של ממשק המשתמש. לדוגמה, אפשר ליצור בורר בממשק המשתמש
שתואם לנכס גלוי ספציפי.
כדי להפעיל את הכלי uiautomatorviewer
:
- מפעילים את אפליקציית היעד במכשיר פיזי.
- מחברים את המכשיר למכונת הפיתוח.
- פותחים חלון טרמינל ומנווטים לספרייה
<android-sdk>/tools/
. - מריצים את הכלי באמצעות הפקודה הבאה:
$ uiautomatorviewer
כדי להציג את מאפייני ממשק המשתמש של האפליקציה:
- בממשק
uiautomatorviewer
, לוחצים על הלחצן צילום מסך של מכשיר. - כדי לראות את רכיבי ממשק המשתמש, מעבירים את העכבר מעל תמונת המצב בחלונית הימנית
זוהה על ידי הכלי
uiautomatorviewer
. הנכסים מפורטים נמוכה יותר את החלונית השמאלית ואת היררכיית הפריסה בחלונית השמאלית העליונה. - אפשר גם ללחוץ על הלחצן השבתה או הפעלה של צומתי NAF כדי לראות את רכיבי ממשק המשתמש שלא נגישים ל-UI Automator. ייתכן שרק מידע מוגבל שזמין לרכיבים האלה.
כדי לקבל מידע נוסף על הסוגים הנפוצים של רכיבי ממשק המשתמש שמסופקים על ידי Android, ראו משתמש ממשק.
מוודאים שהפעילות נגישה
מסגרת הבדיקה של UI Automator מספקת ביצועים טובים יותר באפליקציות שהטמיעו
תכונות של נגישות במכשירי Android. כשמשתמשים ברכיבים של ממשק המשתמש מסוג View
, או
תת-מחלקה של View
מה-SDK, אין צורך להטמיע נגישות
תמיכה, כי הכיתות האלה כבר עשו את זה בשבילכם.
עם זאת, חלק מהאפליקציות משתמשות ברכיבים מותאמים אישית של ממשק המשתמש כדי לספק חוויית משתמש עשירה יותר.
רכיבים כאלה לא יספקו תמיכה אוטומטית בנגישות. אם האפליקציה
מכיל מופעים של מחלקה משנית של View
שהיא לא מה-SDK, יוצרים
להוסיף תכונות נגישות לרכיבים האלה על ידי השלמת
את השלבים הבאים:
- ליצור מחלקה בטון שמרחיבה את ExploreByTouchHelper.
- שיוך מופע של המחלקה החדשה לרכיב ממשק משתמש ספציפי בהתאמה אישית באמצעות קוראת ל-setAccessibilityDelegate().
לקבלת הנחיות נוספות לגבי הוספת תכונות נגישות לתצוגה מותאמת אישית תוכלו לעיין במאמר בנושא יצירת תצוגות מותאמות אישית נגישות. מידע נוסף על שיטות מומלצות כלליות לנגישות ב-Android, ראו יצירת אפליקציות נוספות נגיש.
יצירת שיעור בדיקה של UI Automator
יש לכתוב את שיעור הבדיקה של UI Automator באותו אופן שבו כותבים בדיקת JUnit 4 בכיתה. למידע נוסף על יצירת כיתות בחינה של JUnit 4 ושימוש ב-JUnit 4 טענות נכונות (assertions) והערות, ראו יצירת כיתה של בדיקת יחידה אינסטרומנטלית.
צריך להוסיף את ההערה @RunWith(AndroidJUnit4.class) בתחילת הבדיקה להגדרת הסיווג. צריך גם לציין את המחלקה AndroidJUnitRunner, שסופק ב-AndroidX Test, כברירת המחדל של הכלי להריץ בדיקה. השלב הזה מתואר מפורטים יותר במאמר הרצת בדיקות של אוטומציה של ממשק המשתמש במכשיר או באמולטור.
תטמיעו את מודל התכנות הבא בשיעור הבדיקה של אוטומציה של ממשק המשתמש:
- כדי לגשת למכשיר שרוצים לבדוק, צריך לקבל אובייקט
UiDevice
ה-method getInstance() והעברת אובייקט Instrumentation בתור את הארגומנט. - קבלת אובייקט
UiObject2
כדי לגשת לרכיב בממשק המשתמש שמוצג במכשיר (לדוגמה, התצוגה הנוכחית בחזית), על ידי קריאה המתודה findObject(). - לבצע סימולציה של אינטראקציה ספציפית עם משתמש שתבוצע ברכיב בממשק המשתמש, לפי
קריאה ל-method
UiObject2
, לדוגמה, להתקשר scroll עד() כדי לגלול, ו-setText() כדי לערוך שדה טקסט. ניתן להפעיל את ממשקי ה-API בשלבים 2 ו-3 שוב ושוב לפי הצורך כדי לבדוק אינטראקציות מורכבות יותר של משתמשים שכוללות רכיבים מרובים בממשק המשתמש או רצפים של פעולות משתמש. - לבדוק שממשק המשתמש משקף את המצב או ההתנהגות הצפויים, אחרי שהמשתמשים האלה מתבצעות אינטראקציות ראשוניות.
השלבים האלה מוסברים בפירוט בסעיפים הבאים.
גישה לרכיבי ממשק המשתמש
האובייקט UiDevice
הוא הדרך העיקרית לגשת אל
במצב של המכשיר. בבדיקות שלך, אפשר להפעיל UiDevice
שיטות כדי לבדוק אם יש
את המצב של מאפיינים שונים, כמו הכיוון הנוכחי או גודל התצוגה.
הבדיקה יכולה להשתמש באובייקט UiDevice
כדי לבצע פעולות ברמת המכשיר,
כמו לאלץ את המכשיר לסיבוב ספציפי, לחיצה על חומרת D-pad
ולחיצה על הלחצנים 'דף הבית' ו'תפריט'.
מומלץ להתחיל את הבדיקה ממסך הבית של המכשיר. מאת במסך הבית (או מיקום התחלה אחר שבחרתם במכשיר), אפשר לקרוא ל-methods שמסופקות על ידי UI Automator API כדי לבחור ולבצע אינטראקציה עם רכיבים ספציפיים בממשק המשתמש.
קטע הקוד הבא מראה איך הבדיקה עשויה לקבל מופע של
UiDevice
וסימולציה של לחיצה על לחצן דף הבית:
Kotlin
import org.junit.Before import androidx.test.runner.AndroidJUnit4 import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.By import androidx.test.uiautomator.Until ... private const val BASIC_SAMPLE_PACKAGE = "com.example.android.testing.uiautomator.BasicSample" private const val LAUNCH_TIMEOUT = 5000L private const val STRING_TO_BE_TYPED = "UiAutomator" @RunWith(AndroidJUnit4::class) @SdkSuppress(minSdkVersion = 18) class ChangeTextBehaviorTest2 { private lateinit var device: UiDevice @Before fun startMainActivityFromHomeScreen() { // Initialize UiDevice instance device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) // Start from the home screen device.pressHome() // Wait for launcher val launcherPackage: String = device.launcherPackageName assertThat(launcherPackage, notNullValue()) device.wait( Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT ) // Launch the app val context = ApplicationProvider.getApplicationContext<Context>() val intent = context.packageManager.getLaunchIntentForPackage( BASIC_SAMPLE_PACKAGE).apply { // Clear out any previous instances addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) } context.startActivity(intent) // Wait for the app to appear device.wait( Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)), LAUNCH_TIMEOUT ) } }
Java
import org.junit.Before; import androidx.test.runner.AndroidJUnit4; import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.By; import androidx.test.uiautomator.Until; ... @RunWith(AndroidJUnit4.class) @SdkSuppress(minSdkVersion = 18) public class ChangeTextBehaviorTest { private static final String BASIC_SAMPLE_PACKAGE = "com.example.android.testing.uiautomator.BasicSample"; private static final int LAUNCH_TIMEOUT = 5000; private static final String STRING_TO_BE_TYPED = "UiAutomator"; private UiDevice device; @Before public void startMainActivityFromHomeScreen() { // Initialize UiDevice instance device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); // Start from the home screen device.pressHome(); // Wait for launcher final String launcherPackage = device.getLauncherPackageName(); assertThat(launcherPackage, notNullValue()); device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT); // Launch the app Context context = ApplicationProvider.getApplicationContext(); final Intent intent = context.getPackageManager() .getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE); // Clear out any previous instances intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(intent); // Wait for the app to appear device.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)), LAUNCH_TIMEOUT); } }
בדוגמה, ההצהרה @SdkSuppress(minSdkVersion = 18) עוזרת שהבדיקות יפעלו רק במכשירים עם Android בגרסה 4.3 (רמת API 18) ומעלה, כנדרש על ידי ה-framework של ה-UI Automator.
צריך להשתמש בשיטה findObject()
כדי לאחזר UiObject2
שמייצג
תצוגה שתואמת לקריטריונים מסוימים של בורר. אפשר להשתמש שוב בUiObject2
מופעים שיצרתם בחלקים אחרים של בדיקת האפליקציה, לפי הצורך.
שים לב שמסגרת הבדיקה של האוטומציה של ממשק המשתמש מחפשת במסך הנוכחי כדי
תואם בכל פעם שהבדיקה שלך משתמשת במופע UiObject2
כדי ללחוץ על ממשק משתמש
או שאילתה על מאפיין.
קטע הקוד הבא מראה איך הבדיקה עשויה ליצור UiObject2
מופעים שמייצגים לחצן ביטול ולחצן אישור באפליקציה.
Kotlin
val okButton: UiObject2 = device.findObject( By.text("OK").clazz("android.widget.Button") ) // Simulate a user-click on the OK button, if found. if (okButton != null) { okButton.click() }
Java
UiObject2 okButton = device.findObject( By.text("OK").clazz("android.widget.Button") ); // Simulate a user-click on the OK button, if found. if (okButton != null) { okButton.click(); }
ציון בורר
כדי לגשת לרכיב ספציפי בממשק המשתמש באפליקציה, צריך להשתמש
By
כדי ליצור מכונה של BySelector
. BySelector
מייצג שאילתה לרכיבים ספציפיים בממשק המשתמש המוצג.
אם נמצא יותר מרכיב תואם אחד, הרכיב התואם הראשון
היררכיית הפריסה מוחזרת בתור היעד UiObject2
. כשיוצרים
BySelector
, אפשר לשרשר יחד כמה נכסים כדי לשפר את
לחפש אם לא נמצא רכיב תואם בממשק המשתמש, מוחזר null
.
אפשר להשתמש בשיטה hasChild()
או בשיטה hasDescendant()
כדי למקם
מספר מופעים של BySelector
. לדוגמה, הקוד הבא מראה
איך הבדיקה עשויה לציין חיפוש כדי למצוא את ListView
הראשון
יש רכיב צאצא של ממשק משתמש עם המאפיין text.
Kotlin
val listView: UiObject2 = device.findObject( By.clazz("android.widget.ListView") .hasChild( By.text("Apps") ) )
Java
UiObject2 listView = device.findObject( By.clazz("android.widget.ListView") .hasChild( By.text("Apps") ) );
מומלץ לציין את מצב האובייקט בקריטריונים של הבורר. עבור
לדוגמה, אם רוצים לבחור רשימה של כל הרכיבים המסומנים כדי
לבטל את הסימון שלהם, קוראים לשיטה checked()
כשהארגומנט מוגדר כ-true.
ביצוע פעולות
אחרי שהבדיקה תקבל אובייקט UiObject2
, אפשר לקרוא ל-methods ב:
המחלקה UiObject2
לביצוע אינטראקציות של משתמשים ברכיב של ממשק המשתמש
שמיוצג על ידי האובייקט הזה. תוכלו לציין פעולות כמו:
click()
: לחיצה על מרכז הגבולות הגלויים של הרכיב בממשק המשתמש.drag()
: גרירת האובייקט הזה לקואורדינטות שרירותיות.setText()
: מגדיר את הטקסט בשדה שניתן לעריכה, אחרי ניקוי של תוכן השדה. לעומת זאת, השיטהclear()
מוחקת את הטקסט הקיים בשדה שניתן לעריכה.swipe()
: מבצע את פעולת ההחלקה לכיוון שצוין.scrollUntil()
: מבצע את פעולת הגלילה לכיוון שצוין עד ש-Condition
אוEventCondition
מרוצים.
מסגרת הבדיקה של ממשק המשתמש האוטומטי מאפשרת לשלוח Intent או להפעיל
פעילות בלי להשתמש בפקודות מעטפת, על ידי קבלת הפונקציה Context
אובייקט באמצעות getContext()
.
קטע הקוד הבא מראה איך הבדיקה יכולה להשתמש ב-Intent כדי להפעיל את האפליקציה בבדיקה. הגישה הזו שימושית אם רוצים לבדוק רק את אפליקציית המחשבון ולא אכפת לכם ממרכז האפליקציות.
Kotlin
fun setUp() { ... // Launch a simple calculator app val context = getInstrumentation().context val intent = context.packageManager.getLaunchIntentForPackage(CALC_PACKAGE).apply { addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) } // Clear out any previous instances context.startActivity(intent) device.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT) }
Java
public void setUp() { ... // Launch a simple calculator app Context context = getInstrumentation().getContext(); Intent intent = context.getPackageManager() .getLaunchIntentForPackage(CALC_PACKAGE); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); // Clear out any previous instances context.startActivity(intent); device.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT); }
אימות התוצאות
ה-InstrumentationTestCase מרחיב את TestCase, כך שאפשר להשתמש שיטות רגילות של Assert לבדיקת רכיבי ממשק המשתמש בהחזרת האפליקציה בין התוצאות הצפויות.
קטע הקוד הבא מראה איך הבדיקה יכולה לאתר כמה לחצנים של המחשבון, לוחצים עליהם לפי הסדר ואז מוודאים שהתוצאה הנכונה מוצגת.
Kotlin
private const val CALC_PACKAGE = "com.myexample.calc" fun testTwoPlusThreeEqualsFive() { // Enter an equation: 2 + 3 = ? device.findObject(By.res(CALC_PACKAGE, "two")).click() device.findObject(By.res(CALC_PACKAGE, "plus")).click() device.findObject(By.res(CALC_PACKAGE, "three")).click() device.findObject(By.res(CALC_PACKAGE, "equals")).click() // Verify the result = 5 val result: UiObject2 = device.findObject(By.res(CALC_PACKAGE, "result")) assertEquals("5", result.text) }
Java
private static final String CALC_PACKAGE = "com.myexample.calc"; public void testTwoPlusThreeEqualsFive() { // Enter an equation: 2 + 3 = ? device.findObject(By.res(CALC_PACKAGE, "two")).click(); device.findObject(By.res(CALC_PACKAGE, "plus")).click(); device.findObject(By.res(CALC_PACKAGE, "three")).click(); device.findObject(By.res(CALC_PACKAGE, "equals")).click(); // Verify the result = 5 UiObject2 result = device.findObject(By.res(CALC_PACKAGE, "result")); assertEquals("5", result.getText()); }
הרצת בדיקות של אוטומציה של ממשק המשתמש במכשיר או באמולטור
אפשר להריץ בדיקות של האוטומציה של ממשק המשתמש מ-Android Studio או דרך
בשורת הפקודה. חשוב לציין את AndroidJUnitRunner
כברירת המחדל
הפעלת אינסטרומנטציה בפרויקט.
דוגמאות נוספות
אינטראקציה עם ממשק המשתמש של המערכת
אוטומציה של ממשק המשתמש יכולה לבצע פעולות בכל מה שמופיע במסך, כולל מחוץ לאפליקציה, כפי שמוצג בקטעי הקוד הבאים:
Kotlin
// Opens the System Settings. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) device.executeShellCommand("am start -a android.settings.SETTINGS")
Java
// Opens the System Settings. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.executeShellCommand("am start -a android.settings.SETTINGS");
Kotlin
// Opens the notification shade. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) device.openNotification()
Java
// Opens the notification shade. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.openNotification();
Kotlin
// Opens the Quick Settings shade. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) device.openQuickSettings()
Java
// Opens the Quick Settings shade. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.openQuickSettings();
Kotlin
// Get the system clock. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock")) print(clock.getText())
Java
// Get the system clock. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock")); print(clock.getText());
המתנה להעברות
מעברים בין מסכים עשויים להימשך זמן, ולכן לא ניתן לחזות את משך הזמן שלהם. לכן אמורה להופיע המתנה של UI Automator לאחר ביצוע פעולות. יוצר אוטומטי של ממשק המשתמש מספקת כמה שיטות לכך:
UiDevice.performActionAndWait(Runnable action, EventCondition<U> condition, long timeout)
: לדוגמה, כדי ללחוץ על לחצן ולחכות עד שמופיע חלון חדש, צריך לקרוא למספרdevice.performActionAndWait(() -> button.click(), Until.newWindow(), timeout)
UiDevice.wait(Condition<Object, U> condition, long timeout)
: לדוגמה, כדי לחכות עד שיישמר במכשירUiObject2
מסוים, אפשר להתקשר אלdevice.wait(device.hasObject(By.text("my_text")), timeout);
UiObject2.wait(@NonNull Condition<Object, U> condition, long timeout)
: לדוגמה, כדי להמתין עד שתיבת הסימון מסומנת, אפשר להפעיל את הקריאהcheckbox.wait(Until.checked(true), timeout);
UiObject2.clickAndWait(@NonNull EventCondition<U> condition, long timeout)
: לדוגמה, כדי ללחוץ על לחצן ולחכות עד שמופיע חלון חדש, צריך לקרוא למספרbutton.clickAndWait(Until.newWindow(), timeout);
UiObject2.scrollUntil(@NonNull Direction direction, @NonNull Condition<Object, U> condition)
: לדוגמה, כדי לגלול למטה עד שאובייקט חדש מופיע, קוראים לפונקציהobject.scrollUntil(Direction.DOWN, Until.hasObject(By.text('new_obj')));
UiObject2.scrollUntil(@NonNull Direction direction, @NonNull EventCondition<U> condition)
: לדוגמה, כדי לגלול למטה לחלק התחתון, קוראים לפונקציהobject.scrollUntil(Direction.DOWN, Until.scrollFinished(Direction.DOWN));
קטע הקוד הבא מראה איך להשתמש ב-UI Automator כדי להשבית את Do Not
מצב 'הפרעה' בהגדרות המערכת באמצעות השיטה performActionAndWait()
ממתין למעברים:
Kotlin
@Test @SdkSuppress(minSdkVersion = 21) @Throws(Exception::class) fun turnOffDoNotDisturb() { device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) device.performActionAndWait({ try { device.executeShellCommand("am start -a android.settings.SETTINGS") } catch (e: IOException) { throw RuntimeException(e) } }, Until.newWindow(), 1000) // Check system settings has been opened. Assert.assertTrue(device.hasObject(By.pkg("com.android.settings"))) // Scroll the settings to the top and find Notifications button var scrollableObj: UiObject2 = device.findObject(By.scrollable(true)) scrollableObj.scrollUntil(Direction.UP, Until.scrollFinished(Direction.UP)) val notificationsButton = scrollableObj.findObject(By.text("Notifications")) // Click the Notifications button and wait until a new window is opened. device.performActionAndWait({ notificationsButton.click() }, Until.newWindow(), 1000) scrollableObj = device.findObject(By.scrollable(true)) // Scroll down until it finds a Do Not Disturb button. val doNotDisturb = scrollableObj.scrollUntil( Direction.DOWN, Until.findObject(By.textContains("Do Not Disturb")) ) device.performActionAndWait({ doNotDisturb.click() }, Until.newWindow(), 1000) // Turn off the Do Not Disturb. val turnOnDoNotDisturb = device.findObject(By.text("Turn on now")) turnOnDoNotDisturb?.click() Assert.assertTrue(device.wait(Until.hasObject(By.text("Turn off now")), 1000)) }
Java
@Test @SdkSuppress(minSdkVersion = 21) public void turnOffDoNotDisturb() throws Exception{ device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.performActionAndWait(() -> { try { device.executeShellCommand("am start -a android.settings.SETTINGS"); } catch (IOException e) { throw new RuntimeException(e); } }, Until.newWindow(), 1000); // Check system settings has been opened. assertTrue(device.hasObject(By.pkg("com.android.settings"))); // Scroll the settings to the top and find Notifications button UiObject2 scrollableObj = device.findObject(By.scrollable(true)); scrollableObj.scrollUntil(Direction.UP, Until.scrollFinished(Direction.UP)); UiObject2 notificationsButton = scrollableObj.findObject(By.text("Notifications")); // Click the Notifications button and wait until a new window is opened. device.performActionAndWait(() -> notificationsButton.click(), Until.newWindow(), 1000); scrollableObj = device.findObject(By.scrollable(true)); // Scroll down until it finds a Do Not Disturb button. UiObject2 doNotDisturb = scrollableObj.scrollUntil(Direction.DOWN, Until.findObject(By.textContains("Do Not Disturb"))); device.performActionAndWait(()-> doNotDisturb.click(), Until.newWindow(), 1000); // Turn off the Do Not Disturb. UiObject2 turnOnDoNotDisturb = device.findObject(By.text("Turn on now")); if(turnOnDoNotDisturb != null) { turnOnDoNotDisturb.click(); } assertTrue(device.wait(Until.hasObject(By.text("Turn off now")), 1000)); }
מקורות מידע נוספים
למידע נוסף על השימוש ב-UI Automator בבדיקות Android, אפשר לעיין ב במקורות המידע הבאים.
מסמכי עזר:
דוגמיות
- BasicSample: דוגמת אוטומציה של ממשק משתמש בסיסי.