الاختبار للتأكّد من التغييرات في إعدادات الشاشة باستخدام Espresso Device API

استخدِم واجهة برمجة التطبيقات Espresso Device API لاختبار تطبيقك عندما يخضع الجهاز لتغييرات شائعة في الإعدادات، مثل التدوير وفتح الشاشة. ننصحك باستخدام واجهة برمجة التطبيقات Espresso Device API لتنفيذ إجراءات على مستوى الجهاز إلى جانب قواعد اختبار Jetpack Compose. إذا كنت حديث العهد بكتابة اختبارات واجهة المستخدم في Jetpack Compose، اطّلِع على اختبار تصميم Compose.

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

لاستخدام Espresso Device API، يجب استيفاء الشروط التالية:

  • الإصدار Iguana من "استوديو Android" أو إصدار أحدث
  • الإصدار 8.3 من المكوّن الإضافي لنظام Gradle المتوافق مع Android أو إصدار أحدث
  • الإصدار 33.1.10 من Android Emulator أو إصدار أحدث
  • جهاز Android افتراضي يعمل بالمستوى 24 من واجهة برمجة التطبيقات أو مستوى أحدث

إعداد مشروعك لاستخدام Espresso Device API

لإعداد مشروعك بحيث يتوافق مع Espresso Device API، اتّبِع الخطوات التالية:

  1. للسماح للاختبار بتمرير الأوامر إلى الجهاز الاختباري، أضِف أذونات الشبكة المطلوبة إلى ملف البيان في مجموعة رموز المصدر androidTest:

      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    

    إذا كان الاختبار يستهدف الإصدار 17 من نظام التشغيل Android (المستوى 37 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، عليك أيضًا الإفصاح عن الإذن ACCESS_LOCAL_NETWORK:

      <uses-permission android:name="android.permission.ACCESS_LOCAL_NETWORK" />
    
  2. فعِّل العلامة التجريبية enableEmulatorControl في ملف gradle.properties:

      android.experimental.androidTest.enableEmulatorControl=true
    
  3. فعِّل الخيار emulatorControl في نص البرمجة الخاص بالإصدار على مستوى الوحدة:

    Kotlin

      testOptions {
        emulatorControl {
          enable = true
        }
      }
      

    أنيق

      testOptions {
        emulatorControl {
          enable = true
        }
      }
      
  4. في نص برمجة الإصدار على مستوى الوحدة، استورِد مكتبة Espresso Device إلى مشروعك:

    Kotlin

    dependencies {
      androidTestImplementation("androidx.test.espresso:espresso-device:1.1.0")
    }

    أنيق

    dependencies {
      androidTestImplementation 'androidx.test.espresso:espresso-device:1.1.0'
    }

الاختبار مقارنةً بالتغييرات الشائعة في الإعدادات

تتضمّن واجهة برمجة التطبيقات Espresso Device API حالات متعددة لاتجاه الشاشة وحالات الأجهزة القابلة للطي، ويمكنك استخدامها لتفعيل تغييرات في إعدادات الجهاز. توضّح الأمثلة التالية كيفية تفعيل حالات الجهاز هذه والتحقّق من التغييرات الناتجة في واجهة المستخدم باستخدام قواعد اختبار Compose.

الاختبار على تدوير الشاشة

لاختبار تدوير الشاشة، يمكنك استخدام الفئة ScreenOrientationRule لتحديد اتجاه الجهاز أثناء الاختبار.

في ما يلي مثال على كيفية اختبار ما يحدث لتطبيقك عند تدوير شاشة الجهاز:

  1. أولاً، حدِّد قاعدة اختبار Compose واستخدِم الفئة ScreenOrientationRule لضبط الجهاز على حالة بدء متسقة (مثل الوضع العمودي):

    import androidx.compose.ui.test.assertIsDisplayed
    import androidx.compose.ui.test.assertDoesNotExist
    import androidx.compose.ui.test.junit4.createComposeRule
    import androidx.compose.ui.test.onNodeWithTag
    import androidx.test.espresso.device.EspressoDevice.onDevice
    import androidx.test.espresso.device.action.ScreenOrientation
    import androidx.test.espresso.device.rules.ScreenOrientationRule
    import org.junit.Rule
    import org.junit.Test
    
    class MyConfigurationTest {
    
        // 1. Define the Compose test rule
        @get:Rule
        val composeTestRule = createComposeRule()
    
        // 2. Define the Espresso Device rule for a consistent starting state
        @get:Rule
        val screenOrientationRule = ScreenOrientationRule(ScreenOrientation.PORTRAIT)
    }
    

    إذا كانت الاختبارات تستهدف الإصدار 17 من نظام التشغيل Android (المستوى 37 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، تتطلّب واجهة برمجة التطبيقات Espresso Device API الإذن ACCESS_LOCAL_NETWORK. يجب التأكّد من منح هذا الإذن قبل تنفيذ قاعدة ScreenOrientationRule. استخدِم RuleChain في JUnit لتشغيل قاعدة GrantPermissionRule أولاً:

    import androidx.test.rule.GrantPermissionRule
    import org.junit.rules.RuleChain
    
    class MyConfigurationTest {
        val grantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_LOCAL_NETWORK)
        val composeTestRule = createComposeRule()
        val screenOrientationRule = ScreenOrientationRule(ScreenOrientation.PORTRAIT)
    
        @get:Rule
        val chain = RuleChain
            .outerRule(grantPermissionRule)
            .around(composeTestRule)
            .around(screenOrientationRule)
    }
    
  2. أنشئ اختبارًا يضبط الجهاز على الوضع الأفقي أثناء تنفيذ الاختبار:

    @Test
    fun myRotationTest() {
      ...
      // Sets the device to landscape orientation during test execution.
      onDevice().setScreenOrientation(ScreenOrientation.LANDSCAPE)
      ...
    }
    
  3. بعد تدوير الشاشة، استخدِم composeTestRule للتأكّد من أنّ العناصر القابلة للإنشاء تتكيّف مع الحالة الجديدة على النحو المتوقّع.

    @Test
    fun myRotationTest() {
      ...
      // Sets the device to landscape orientation during test execution.
      onDevice().setScreenOrientation(ScreenOrientation.LANDSCAPE)
      composeTestRule.onNodeWithTag("NavRail").assertIsDisplayed()
      composeTestRule.onNodeWithTag("BottomBar").assertDoesNotExist()
    }
    

الاختبار عند فتح الشاشة

في ما يلي مثال على كيفية اختبار ما يحدث لتطبيقك إذا كان على جهاز قابل للطي وتم فتح الشاشة:

  1. أولاً، اختبِر الجهاز وهو مطوي من خلال الاتصال بالرقم onDevice().setClosedMode(). تأكَّد من أنّ العناصر القابلة للإنشاء تتكيّف مع عرض الشاشة المضغوط.

    @Test
    fun myUnfoldedTest() {
      onDevice().setClosedMode()
      composeTestRule.onNodeWithTag("BottomBar").assertIsDisplayed()
      composeTestRule.onNodeWithTag("NavRail").assertDoesNotExist()
      ...
    }
    
  2. للانتقال إلى حالة الفتح الكامل، استخدِم onDevice().setFlatMode(). تأكَّد من أنّ العناصر القابلة للإنشاء تتكيّف مع فئة الحجم الموسّعة.

    @Test
    fun myUnfoldedTest() {
      onDevice().setClosedMode()
      ...
      onDevice().setFlatMode()
      composeTestRule.onNodeWithTag("NavRail").assertIsDisplayed()
      composeTestRule.onNodeWithTag("BottomBar").assertDoesNotExist()
    }
    

تحديد الأجهزة التي تحتاج إليها الاختبارات

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

على سبيل المثال، لتحديد أنّه يجب إجراء اختبار على الأجهزة التي تتيح الطي إلى وضع مسطّح فقط، أضِف الرمز @RequiresDeviceMode التالي إلى الاختبار:

@Test
@RequiresDeviceMode(mode = FLAT)
fun myUnfoldedTest() {
  ...
}