استخدِم واجهة برمجة التطبيقات 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، اتّبِع الخطوات التالية:
للسماح للاختبار بتمرير الأوامر إلى الجهاز الاختباري، أضِف أذونات الشبكة المطلوبة إلى ملف البيان في مجموعة رموز المصدر
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" />فعِّل العلامة التجريبية
enableEmulatorControlفي ملفgradle.properties:android.experimental.androidTest.enableEmulatorControl=trueفعِّل الخيار
emulatorControlفي نص البرمجة الخاص بالإصدار على مستوى الوحدة:Kotlin
testOptions { emulatorControl { enable = true } }
أنيق
testOptions { emulatorControl { enable = true } }
في نص برمجة الإصدار على مستوى الوحدة، استورِد مكتبة 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 لتحديد اتجاه الجهاز أثناء الاختبار.
في ما يلي مثال على كيفية اختبار ما يحدث لتطبيقك عند تدوير شاشة الجهاز:
أولاً، حدِّد قاعدة اختبار 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) }أنشئ اختبارًا يضبط الجهاز على الوضع الأفقي أثناء تنفيذ الاختبار:
@Test fun myRotationTest() { ... // Sets the device to landscape orientation during test execution. onDevice().setScreenOrientation(ScreenOrientation.LANDSCAPE) ... }بعد تدوير الشاشة، استخدِم
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() }
الاختبار عند فتح الشاشة
في ما يلي مثال على كيفية اختبار ما يحدث لتطبيقك إذا كان على جهاز قابل للطي وتم فتح الشاشة:
أولاً، اختبِر الجهاز وهو مطوي من خلال الاتصال بالرقم
onDevice().setClosedMode(). تأكَّد من أنّ العناصر القابلة للإنشاء تتكيّف مع عرض الشاشة المضغوط.@Test fun myUnfoldedTest() { onDevice().setClosedMode() composeTestRule.onNodeWithTag("BottomBar").assertIsDisplayed() composeTestRule.onNodeWithTag("NavRail").assertDoesNotExist() ... }للانتقال إلى حالة الفتح الكامل، استخدِم
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() {
...
}