UI Automator هو إطار عمل لاختبار واجهة المستخدم مناسب لاختبار واجهة المستخدم عبر التطبيقات
عبر التطبيقات عبر النظام والتطبيقات المثبّتة. تتيح لك واجهات برمجة تطبيقات UI Automator التفاعل مع العناصر المرئية على الجهاز بغض النظر عن Activity
محل التركيز، لذلك تسمح لك هذه الواجهة بتنفيذ عمليات مثل فتح قائمة الإعدادات أو مشغّل التطبيقات في جهاز اختبار. يمكن أن يبحث الاختبار عن مكون واجهة المستخدم عن طريق
استخدام وسائل وصف ملائمة مثل النص المعروض في هذا المكون أو
وصف المحتوى.
إنّ إطار عمل اختبار UI Automator هو واجهة برمجة تطبيقات تستند إلى قياس الأداء، ويعمل مع مُشغِّل الاختبار AndroidJUnitRunner
. وهو مناسب تمامًا لكتابة الاختبارات الآلية على شكل مربع معتم، حيث لا يعتمد رمز الاختبار على تفاصيل التنفيذ الداخلي للتطبيق المستهدف.
تشمل الميزات الرئيسية لإطار عمل اختبار واجهة المستخدم التلقائية ما يلي:
- واجهة برمجة تطبيقات لاسترداد معلومات الحالة وتنفيذ العمليات على الجهاز المستهدف. لمزيد من المعلومات، يُرجى الاطِّلاع على الوصول إلى حالة الجهاز.
- واجهات برمجة التطبيقات التي تتيح اختبار واجهة المستخدم بين التطبيقات لمزيد من المعلومات، يُرجى الاطّلاع على واجهات برمجة تطبيقات واجهة المستخدم التلقائية.
جارٍ الوصول إلى حالة الجهاز
يوفِّر إطار عمل اختبار واجهة المستخدم التلقائية فئة UiDevice
للوصول إلى
العمليات وتنفيذها على الجهاز الذي يتم تشغيل التطبيق المستهدَف عليه. يمكنك استدعاء طرقه للوصول إلى خصائص الجهاز مثل الاتجاه الحالي أو
حجم العرض. تتيح لك الفئة UiDevice
أيضًا تنفيذ الإجراءات التالية:
- غيِّر دوران الجهاز.
- اضغط على مفاتيح الأجهزة، مثل "رفع الصوت".
- اضغط على أزرار الرجوع أو الصفحة الرئيسية أو القائمة.
- افتح مركز الإشعارات.
- خُذ لقطة شاشة للنافذة الحالية.
على سبيل المثال، لمحاكاة الضغط على زر الشاشة الرئيسية، يمكنك استدعاء الطريقة UiDevice.pressHome()
.
واجهات برمجة التطبيقات UI Automator
تتيح لك واجهات برمجة التطبيقات UI Automator كتابة اختبارات قوية دون الحاجة إلى معرفة تفاصيل تنفيذ التطبيق الذي تستهدفه. يمكنك استخدام واجهات برمجة التطبيقات هذه لالتقاط ومعالجة مكونات واجهة المستخدم عبر تطبيقات متعددة:
UiObject2
: يمثل عنصر واجهة مستخدم مرئيًا على الجهاز.BySelector
: يحدّد معايير مطابقة عناصر واجهة المستخدم.By
: تنشئBySelector
بطريقة موجزة.Configurator
: يتيح لك هذا الخيار ضبط المَعلمات الرئيسية لإجراء اختبارات واجهة المستخدم Automator.
على سبيل المثال، يوضّح الرمز التالي كيفية كتابة نص برمجي تجريبي لفتح تطبيق 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);
إعداد واجهة المستخدم التلقائية
قبل إنشاء اختبار واجهة المستخدم باستخدام UI Automator، احرص على ضبط موقع رمز مصدر الاختبار وتبعيات المشروع، كما هو موضّح في إعداد المشروع على AndroidX Test.
في ملف build.gradle
لوحدة تطبيق Android، يجب ضبط مرجع
تبعية إلى مكتبة UI Automator:
Kotlin
dependencies {
...
androidTestImplementation('androidx.test.uiautomator:uiautomator:2.3.0-alpha03')
}
رائع
dependencies {
...
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.3.0-alpha03'
}
لتحسين اختبار UI Automator، يجب عليك أولاً فحص مكونات واجهة المستخدم للتطبيق المستهدف والتأكد من إمكانية الوصول إليها. تم وصف نصائح التحسين هذه في القسمين التاليين.
فحص واجهة المستخدم على الجهاز
قبل تصميم الاختبار، افحص مكونات واجهة المستخدم التي تظهر على الجهاز. للتأكّد من إمكانية وصول اختبارات UI Automator إلى هذه المكوّنات،
تأكَّد من أنّ هذه المكوّنات تحتوي على تصنيفات نصية مرئية أو قيم android:contentDescription
أو كليهما.
توفّر أداة uiautomatorviewer
واجهة مرئية ملائمة لفحص
التسلسل الهرمي للتنسيق والاطّلاع على خصائص مكوّنات واجهة المستخدم التي تظهر
في مقدّمة الجهاز. تتيح لك هذه المعلومات إنشاء المزيد من الاختبارات
المصغرة باستخدام UI Automator. على سبيل المثال، يمكنك إنشاء أداة اختيار واجهة المستخدم
تتطابق مع موقع مرئي معيّن.
لتشغيل أداة "uiautomatorviewer
":
- تشغيل التطبيق المستهدف على جهاز مادي.
- اربط الجهاز بجهاز التطوير.
- افتح نافذة طرفية وانتقِل إلى دليل
<android-sdk>/tools/
. - شغِّل الأداة باستخدام الأمر التالي:
$ uiautomatorviewer
لعرض خصائص واجهة المستخدم لتطبيقك:
- في واجهة
uiautomatorviewer
، انقر على زر لقطة شاشة للجهاز. - مرِّر مؤشر الماوس فوق اللقطة في اللوحة اليمنى للاطّلاع على مكوّنات واجهة المستخدم
التي تحدّدها أداة
uiautomatorviewer
. يتم سرد الخصائص في اللوحة اليمنى السفلية والتسلسل الهرمي للتخطيط في اللوحة اليمنى العليا. - يمكنك، إن أردت، النقر على الزر تبديل عقد NAF لعرض مكوّنات واجهة المستخدم التي لا يمكن وصولها إلى UI Automator. قد تتوفر معلومات محدودة فقط لهذه المكونات.
للتعرّف على الأنواع الشائعة لمكونات واجهة المستخدم التي يوفّرها Android، يمكنك الاطّلاع على واجهة المستخدم.
التأكّد من إمكانية الوصول إلى نشاطك
يحقِّق إطار عمل اختبار واجهة المستخدم التلقائية أداءً أفضل على التطبيقات التي نفّذت
ميزات تسهيل الاستخدام في نظام التشغيل Android. عند استخدام عناصر واجهة المستخدم من النوع View
، أو فئة فرعية من View
من حزمة تطوير البرامج (SDK)، لن تحتاج إلى تنفيذ دعم تسهيل الاستخدام، لأنّ هذه الصفوف قد فعلت ذلك لك.
ومع ذلك، تستخدم بعض التطبيقات عناصر واجهة المستخدم المخصّصة لتوفير تجربة أفضل للمستخدم.
لن تتيح هذه العناصر إمكانية الوصول التلقائي. إذا كان تطبيقك يحتوي على مثيلات لفئة فرعية من View
غير مضمّنة في حزمة تطوير البرامج (SDK)، احرص على إضافة ميزات تسهيل الاستخدام إلى هذه العناصر من خلال إكمال الخطوات التالية:
- أنشئ فئة ملموسة تمتد إلى ExploreByTouchHelper.
- اربط مثيلاً من فئتك الجديدة بعنصر مخصص في واجهة المستخدم عن طريق استدعاء setAccessibilitydisable().
للحصول على إرشادات إضافية حول إضافة ميزات تسهيل الاستخدام إلى عناصر طريقة العرض المخصّصة، يُرجى الاطّلاع على إنشاء طرق عرض مخصّصة يمكن الوصول إليها. لمزيد من المعلومات حول أفضل الممارسات العامة لتسهيل الاستخدام على Android، يُرجى الاطّلاع على القسم تسهيل استخدام التطبيقات.
إنشاء فئة اختبار لواجهة المستخدم
يجب كتابة فئة اختبار UI Automator بالطريقة نفسها المتبعة في فئة الاختبار JUnit 4. لمعرفة المزيد من المعلومات حول إنشاء صفوف اختبار JUnit 4 واستخدام التأكيدات والتعليقات التوضيحية للوحدة 4، يمكنك الاطلاع على إنشاء فئة اختبار الوحدة المصغرة.
أضِف التعليق التوضيحي @RunWith(AndroidJUnit4.class) في بداية تعريف فئة الاختبار. وعليك أيضًا تحديد الفئة AndroidJUnitRunner المتوفّرة في AndroidX Test لتكون المشغّل التلقائي للاختبار. يتم توضيح هذه الخطوة بمزيد من التفصيل في إجراء اختبارات واجهة المستخدم التلقائية على جهاز أو محاكي.
نفِّذ نموذج البرمجة التالي في فئة اختبار UI Automator:
- يمكنك الحصول على كائن
UiDevice
للوصول إلى الجهاز الذي تريد اختباره، وذلك من خلال استدعاء طريقة getInstance() وتمرير كائن Hardwareation كوسيطة. - يمكنك الحصول على كائن
UiObject2
للوصول إلى أحد مكونات واجهة المستخدم التي يتم عرضها على الجهاز (مثل العرض الحالي في المقدّمة)، من خلال استدعاء طريقة findObject(). - يمكنك محاكاة تفاعل مستخدم معيّن لتنفيذه على مكوِّن واجهة المستخدم هذا من خلال
استدعاء طريقة
UiObject2
. على سبيل المثال، يمكنك استدعاء scrollUntill() للتمرير وsetText() لتعديل حقل نصي. يمكنك استدعاء واجهات برمجة التطبيقات في الخطوتين 2 و3 بشكل متكرر حسب الضرورة لاختبار تفاعلات المستخدم الأكثر تعقيدًا التي تشمل مكونات واجهة المستخدم المتعددة أو تسلسلات من إجراءات المستخدم. - تحقق من أن واجهة المستخدم تعكس الحالة أو السلوك المتوقع، بعد تنفيذ تفاعلات المستخدم هذه.
يتم تناول هذه الخطوات بمزيد من التفصيل في الأقسام التالية.
الوصول إلى مكونات واجهة المستخدم
الكائن UiDevice
هو الطريقة الأساسية التي يمكنك من خلالها الوصول إلى حالة الجهاز ومعالجتها. وفي اختباراتك، يمكنك استدعاء طرق UiDevice
للتحقّق من حالة الخصائص المختلفة، مثل الاتجاه الحالي أو حجم العرض.
يمكن أن يستخدم الاختبار الكائن UiDevice
لتنفيذ إجراءات على مستوى الجهاز،
مثل فرض تدوير معيّن على الجهاز والضغط على أزرار "لوحة التحكّم"
والنقر على زرَّي "الصفحة الرئيسية" و"القائمة".
ومن الممارسات الجيدة أن تبدأ الاختبار من الشاشة الرئيسية للجهاز. من الشاشة الرئيسية (أو أي موقع بدء آخر اخترته في الجهاز)، يمكنك استدعاء الطرق التي تقدمها واجهة برمجة التطبيقات 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) في ضمان تشغيل الاختبارات فقط على الأجهزة التي تعمل بالإصدار 4.3 من نظام التشغيل Android (المستوى 18 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، على النحو المطلوب في إطار عمل أداة 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
يحتوي على عنصر واجهة مستخدم فرعي مع السمة النصية.
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
، يمكنك استدعاء الطرق في الفئة UiObject2
لإجراء تفاعلات المستخدم على مكوّن واجهة المستخدم الذي يمثّله ذلك العنصر. يمكنك تحديد مثل هذه الإجراءات:
click()
: النقر على وسط الحدود المرئية لعنصر واجهة المستخدم.drag()
: لسحب هذا الكائن إلى الإحداثيات العشوائية.setText()
: لضبط النص في حقل قابل للتعديل، بعد محو محتوى الحقل. وعلى العكس من ذلك، تمحو طريقةclear()
النص الحالي في حقل قابل للتعديل.swipe()
: لتنفيذ إجراء التمرير السريع نحو الاتجاه المحدد.scrollUntil()
: ينفِّذ إجراء الانتقال نحو الاتجاه المحدّد حتى يتم تنفيذ الإجراءCondition
أوEventCondition
.
يتيح لك إطار عمل اختبار واجهة المستخدم Automator إرسال عنصر Intent أو بدء
نشاط بدون استخدام أوامر واجهة الأوامر، من خلال الحصول على عنصر السياق
من خلال 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); }
التحقّق من النتائج
يوسع ElementationTestCase حالة TestCase، بحيث يمكنك استخدام طرق JUnit 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()); }
إجراء اختبارات واجهة المستخدم التلقائية على جهاز أو محاكي
يمكنك إجراء اختبارات واجهة المستخدم Automator من استوديو Android أو من
سطر الأوامر. احرص على تحديد AndroidJUnitRunner
باعتباره برنامج تشغيل الأدوات
التلقائي في مشروعك.
مزيد من الأمثلة
التفاعل مع واجهة مستخدم النظام
يمكن لـ UI Automator التفاعل مع كل شيء على الشاشة، بما في ذلك عناصر النظام خارج تطبيقك، كما هو موضح في مقتطفات الرمز التالية:
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());
انتظار عمليات النقل
![إيقاف الإزعاج](https://developer.android.google.cn/static/images/testing/uiautomator_turn_off_disturb.gif?authuser=5&hl=ar)
يمكن أن تستغرق انتقالات الشاشة بعض الوقت والتنبؤ بمدتها غير موثوق، لذا يجب أن تطلب من واجهة المستخدم Automator الانتظار بعد تنفيذ العمليات. توفِّر أداة 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));
.
يعرض مقتطف الرمز التالي كيفية استخدام واجهة المستخدم التلقائية لإيقاف وضع "عدم الإزعاج" في "إعدادات النظام" باستخدام طريقة 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، يُرجى الرجوع إلى الموارد التالية.
المستندات المرجعية:
عيّنات
- Basicعيّن: نموذج "أداة التشغيل الآلي لواجهة المستخدم الأساسية".