كتابة الاختبارات المبرمجة باستخدام واجهة المستخدم التلقائية

UI Automator هو إطار عمل لاختبار واجهة المستخدم مناسب لاختبار واجهة المستخدم عبر التطبيقات عبر النظام والتطبيقات المثبّتة. تتيح لك واجهات برمجة التطبيقات UI Automator إمكانية التفاعل مع العناصر المرئية على الجهاز، بغض النظر عن Activity محل التركيز، وبذلك تسمح لك بتنفيذ عمليات مثل فتح قائمة الإعدادات أو مشغّل التطبيقات في جهاز اختبار. يمكن أن يبحث الاختبار عن أحد مكونات واجهة المستخدم عن طريق استخدام كلمات وصفية ملائمة مثل النص المعروض في هذا المكون أو وصف محتواه.

إنّ إطار عمل اختبار UI Automator هو واجهة برمجة تطبيقات قائمة على الأدوات ويعمل مع برنامج تشغيل AndroidJUnitRunner للاختبار. وهو مناسب تمامًا لكتابة اختبارات تلقائية بنمط مربع مبهم، حيث لا يعتمد رمز الاختبار على تفاصيل التنفيذ الداخلي للتطبيق المستهدف.

تشمل الميزات الرئيسية لإطار عمل اختبار واجهة المستخدم التلقائية ما يلي:

جارٍ الوصول إلى حالة الجهاز

يوفر إطار عمل اختبار UI Automator فئة UiDevice للوصول إلى العمليات وتنفيذها على الجهاز الذي يتم تشغيل التطبيق المستهدف عليه. يمكنك استدعاء طرقه للوصول إلى خصائص الجهاز مثل الاتجاه الحالي أو حجم العرض. تتيح لك الفئة UiDevice أيضًا تنفيذ الإجراءات التالية:

  1. غيِّر تدوير الجهاز.
  2. اضغط على مفاتيح الجهاز، مثل "رفع الصوت".
  3. اضغط على أزرار الرجوع أو الصفحة الرئيسية أو القائمة.
  4. فتح مركز الإشعارات
  5. التقط لقطة شاشة للنافذة الحالية.

على سبيل المثال، لمحاكاة الضغط على زر الشاشة الرئيسية، يمكنك استدعاء طريقة UiDevice.pressHome().

واجهات برمجة تطبيقات UI Automator

تتيح لك واجهات برمجة التطبيقات UI Automator كتابة اختبارات قوية دون الحاجة إلى معرفة تفاصيل تنفيذ التطبيق الذي تستهدفه. يمكنك استخدام واجهات برمجة التطبيقات هذه لالتقاط ومعالجة مكونات واجهة المستخدم عبر تطبيقات متعددة:

  • 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()

جافا


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

قبل إنشاء اختبار واجهة المستخدم باستخدام UI Automator، احرص على ضبط موقع رمز مصدر الاختبار وتبعيات المشروع، كما هو موضّح في إعداد المشروع لاختبار AndroidX.

في ملف 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، يجب أولاً فحص مكونات واجهة المستخدم للتطبيق المستهدف والتأكد من إمكانية الوصول إليها. تم وصف نصائح التحسين هذه في القسمين التاليين.

فحص واجهة المستخدم على الجهاز

قبل تصميم الاختبار، افحص مكونات واجهة المستخدم التي تظهر على الجهاز. ولضمان إمكانية وصول اختبارات واجهة المستخدم التلقائية إلى هذه المكوّنات، تحقّق من أنّ هذه المكوّنات تحتوي على تصنيفات نصية مرئية أو قيم android:contentDescription أو كليهما.

توفّر أداة uiautomatorviewer واجهة مرئية ملائمة لفحص التسلسل الهرمي للتنسيق والاطّلاع على خصائص مكونات واجهة المستخدم التي تظهر في مقدّمة الجهاز. تتيح لك هذه المعلومات إنشاء المزيد من الاختبارات المصغرة باستخدام UI Automator. على سبيل المثال، يمكنك إنشاء أداة اختيار لواجهة المستخدم تتطابق مع موقع مرئي محدّد.

لتشغيل أداة "uiautomatorviewer":

  1. تشغيل التطبيق المستهدف على جهاز مادي.
  2. اربط الجهاز بجهاز التطوير.
  3. افتح نافذة طرفية وانتقِل إلى دليل <android-sdk>/tools/.
  4. شغّل الأداة باستخدام الأمر التالي:
 $ uiautomatorviewer

لعرض خصائص واجهة المستخدم لتطبيقك:

  1. في واجهة uiautomatorviewer، انقر على زر لقطة شاشة الجهاز.
  2. مرِّر مؤشر الماوس فوق اللقطة في اللوحة اليمنى للاطّلاع على مكوّنات واجهة المستخدم التي تحدّدها أداة uiautomatorviewer. يتم سرد الخصائص في اللوحة السفلية اليمنى والتسلسل الهرمي للتخطيط في اللوحة العلوية اليمنى.
  3. اختياريًا، انقر على الزر تبديل عقد NAF لعرض مكونات واجهة المستخدم التي لا يمكن لـ UI Automator الوصول إليها. قد تتوفر معلومات محدودة فقط لهذه المكونات.

للتعرّف على الأنواع الشائعة لمكونات واجهة المستخدم التي يوفّرها Android، يمكنك الاطّلاع على واجهة المستخدم.

التأكد من سهولة الوصول إلى نشاطك

يحقق إطار عمل اختبار UI Automator أداءً أفضل على التطبيقات التي نفذّت ميزات إمكانية الوصول في Android. عند استخدام عناصر واجهة المستخدم من النوع View أو فئة فرعية من View من حزمة تطوير البرامج (SDK)، لن تحتاج إلى تنفيذ دعم تسهيل الاستخدام، لأنّ هذه الفئات قد فعلت ذلك نيابةً عنك.

تستخدم بعض التطبيقات عناصر واجهة المستخدم المخصَّصة لتوفير تجربة أكثر ثراءً للمستخدم. ولن توفر هذه العناصر إمكانية الوصول التلقائي. إذا كان تطبيقك يحتوي على مثيلات لفئة فرعية من View غير متوفّرة في حزمة تطوير البرامج (SDK)، احرص على إضافة ميزات تسهيل الاستخدام إلى هذه العناصر من خلال إكمال الخطوات التالية:

  1. أنشئ فئة ملموسة تمتد إلى ExploreByTouchHelper.
  2. اربط مثيلاً من الفئة الجديدة بعنصر مخصّص في واجهة المستخدم من خلال استدعاء setAccessibilitySUBSCRIPTION().

للحصول على إرشادات إضافية حول إضافة ميزات إمكانية الوصول إلى عناصر طريقة العرض المخصّصة، راجع إنشاء طرق عرض مخصّصة يمكن الوصول إليها. لمزيد من المعلومات حول أفضل الممارسات العامة لإمكانية الوصول على Android، راجع تسهيل الوصول إلى التطبيقات.

إنشاء صف لاختبار UI Automator

يجب كتابة فئة اختبار UI Automator بالطريقة نفسها التي تتم بها كتابة فئة اختبار JUnit 4. لمعرفة المزيد من المعلومات حول إنشاء صفوف اختبار JUnit 4 واستخدام التأكيدات والتعليقات التوضيحية لوحدة JUnit 4، يمكنك الاطلاع على إنشاء فئة اختبار الوحدة الآلية.

أضِف التعليق التوضيحي @RunWith(AndroidJUnit4.class) في بداية تعريف فئة الاختبار. وعليك أيضًا تحديد الفئة AndroidJUnitRunner الواردة في اختبار AndroidX Test لتكون ضِمن برنامج الاختبار التلقائي. يمكنك الاطّلاع على هذه الخطوة بالتفصيل في إجراء اختبارات واجهة المستخدم التلقائية على جهاز أو محاكي.

نفِّذ نموذج البرمجة التالي في فئة اختبار UI Automator:

  1. احصل على كائن UiDevice للوصول إلى الجهاز الذي تريد اختباره، وذلك من خلال استدعاء طريقة getInstance() وتمرير كائن Hardwareation كوسيطة.
  2. يمكنك الحصول على كائن UiObject2 للوصول إلى مكوِّن واجهة المستخدم المعروض على الجهاز (على سبيل المثال، العرض الحالي في المقدّمة)، من خلال استدعاء طريقة findObject().
  3. يمكنك محاكاة تفاعل مستخدم معيّن لتنفيذه على مكوِّن واجهة المستخدم هذا، من خلال استدعاء طريقة UiObject2، على سبيل المثال، يمكنك استدعاء scrollUntil() للتمرير، وsetText() لتعديل حقل نصي. يمكنك استدعاء واجهات برمجة التطبيقات في الخطوتين 2 و3 بشكل متكرر حسب الضرورة لاختبار تفاعلات المستخدم الأكثر تعقيدًا التي تتضمن العديد من مكونات واجهة المستخدم أو تسلسلات من إجراءات المستخدم.
  4. تحقق من أن واجهة المستخدم تعكس الحالة أو السلوك المتوقع، بعد تنفيذ تفاعلات المستخدم هذه.

يتم تناول هذه الخطوات بمزيد من التفاصيل في الأقسام أدناه.

الوصول إلى مكونات واجهة المستخدم

الكائن 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
    )
  }
}

جافا


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()
}

جافا


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")
        )
)

جافا


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.

يسمح لك إطار عمل اختبار UI 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)
}

جافا


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);
}

التحقّق من النتائج

يوسّع دالة HardwareationTestCase 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)
}

جافا


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());
}

إجراء اختبارات UI Automator على جهاز أو محاكي

يمكنك إجراء اختبارات UI Automator من استوديو Android أو من سطر الأوامر. احرص على تحديد AndroidJUnitRunner كمشغّل تلقائي للمعدّات في مشروعك.

مزيد من الأمثلة

التفاعل مع واجهة مستخدم النظام

يمكن لـ UI Automator التفاعل مع كل شيء على الشاشة، بما في ذلك عناصر النظام خارج التطبيق، كما هو موضح في مقتطفات الرمز التالية:

لغة Kotlin


// Opens the System Settings.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.executeShellCommand("am start -a android.settings.SETTINGS")

جافا


// 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()

جافا


// Opens the notification shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.openNotification();

لغة Kotlin


// Opens the Quick Settings shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.openQuickSettings()

جافا


// 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())

جافا


// Get the system clock.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock"));
print(clock.getText());

انتظار عمليات النقل

إيقاف الإزعاج
الشكل 1. تعمل ميزة UI Automator على إيقاف وضع "عدم الإزعاج" على جهاز اختبار.

يمكن أن تستغرق انتقالات الشاشة بعض الوقت والتنبؤ بمدتها غير موثوق، لذا يجب أن تطلب من UI Automator الانتظار بعد تنفيذ العمليات. UI Automator يوفر طرقًا متعددة لذلك:

يوضّح مقتطف الرمز التالي كيفية استخدام UI Automator لإيقاف وضع "عدم الإزعاج" في إعدادات النظام باستخدام طريقة 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))
}

جافا


@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، يُرجى الرجوع إلى الموارد التالية.

الوثائق المرجعية:

عيّنات

  • PrimarySample: نموذج لأداة التشغيل الآلي لواجهة المستخدم الأساسية.