يمكنك اختبار تطبيق Compose بأساليب وأنماط راسخة.
إجراء الاختبار بشكل منعزل
يتيح لك ComposeTestRule
بدء نشاط يعرض أي عنصر قابل للإنشاء:
تطبيقك الكامل أو شاشة واحدة أو عنصر صغير. ومن الممارسات الجيدة أيضًا التحقّق من أنّ العناصر القابلة للإنشاء مغلّفة بشكل صحيح وأنّها تعمل بشكل مستقل، ما يسمح باختبار واجهة المستخدم بشكل أسهل وأكثر تركيزًا.
ولا يعني ذلك أنّه يجب عليك إنشاء اختبارات واجهة المستخدم فقط. تعد اختبارات واجهة المستخدم تحديد نطاق أجزاء أكبر من واجهة المستخدم مهمة جدًا أيضًا.
الوصول إلى النشاط والموارد بعد إعداد المحتوى الخاص بك
وفي كثير من الأحيان، تحتاج إلى ضبط المحتوى قيد الاختبار باستخدام
composeTestRule.setContent
وتحتاج أيضًا إلى الوصول إلى موارد الأنشطة، مثلاً لتأكيد تطابق النص المعروض مع مورد سلسلة. ومع ذلك، لا يمكنك استدعاء setContent
على قاعدة تم إنشاؤها باستخدام createAndroidComposeRule()
إذا كان النشاط يستدعي ذلك.
أحد الأنماط الشائعة لتحقيق ذلك هو إنشاء AndroidComposeTestRule
باستخدام نشاط فارغ، مثل ComponentActivity
.
class MyComposeTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
@Test
fun myTest() {
// Start the app
composeTestRule.setContent {
MyAppTheme {
MainScreen(uiState = exampleUiState, /*...*/)
}
}
val continueLabel = composeTestRule.activity.getString(R.string.next)
composeTestRule.onNodeWithText(continueLabel).performClick()
}
}
يُرجى العِلم أنّه يجب إضافة ComponentActivity
إلى ملف AndroidManifest.xml
الخاص بالتطبيق. قم بتمكين ذلك عن طريق إضافة هذه التبعية
إلى وحدتك:
debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")
خصائص المعنى المخصّص
يمكنك إنشاء سمات دلالات مخصّصة لعرض المعلومات للاختبارات.
لإجراء ذلك، يجب تحديد سمة SemanticsPropertyKey
جديدة وإتاحتها باستخدام السمة SemanticsPropertyReceiver
.
// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey
استخدِم الآن هذه السمة في أداة تعديل semantics
:
val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
modifier = Modifier.semantics { pickedDate = datePickerValue }
)
من الاختبارات، استخدِم SemanticsMatcher.expectValue
لتأكيد قيمة الموقع:
composeTestRule
.onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
.assertExists()
التأكّد من استعادة الحالة
تحقَّق من استعادة حالة عناصر Compose بشكل صحيح عند
إعادة إنشاء النشاط أو العملية. يمكنك إجراء عمليات التحقق هذه بدون الاعتماد على
إعادة إنشاء النشاط مع صف StateRestorationTester
.
تتيح لك هذه الفئة محاكاة إعادة إنشاء عنصر قابل للإنشاء. يُعدّ التحقّق من تنفيذ rememberSaveable
مفيدًا على وجه الخصوص.
class MyStateRestorationTests {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun onRecreation_stateIsRestored() {
val restorationTester = StateRestorationTester(composeTestRule)
restorationTester.setContent { MainScreen() }
// TODO: Run actions that modify the state
// Trigger a recreation
restorationTester.emulateSavedInstanceStateRestore()
// TODO: Verify that state has been correctly restored.
}
}
اختبار الإعدادات المختلفة للأجهزة
يجب أن تتكيّف تطبيقات Android مع العديد من الظروف المتغيّرة، مثل أحجام النوافذ واللغات وأحجام الخطوط والمظاهر الداكنة والفاتحة وغير ذلك. تُستمَد معظم هذه الحالات من القيم على مستوى الجهاز التي يتحكّم فيها المستخدم ويتم الكشف عنها من خلال
مثيل Configuration
الحالي. يعد اختبار الإعدادات المختلفة
مباشرةً في الاختبار صعبًا لأنّ الاختبار يجب أن يضبط الخصائص على مستوى الجهاز.
DeviceConfigurationOverride
هي واجهة برمجة تطبيقات للاختبار فقط تتيح لك محاكاة
إعدادات الأجهزة المختلفة بطريقة مترجَمة لمحتوى @Composable
الخاضع للاختبار.
يحتوي العنصر المصاحب لـ DeviceConfigurationOverride
على وظائف الإضافات التالية، والتي تلغي خصائص الإعداد على مستوى الجهاز:
DeviceConfigurationOverride.DarkMode()
: لإلغاء النظام إلى المظهر الداكن أو المظهر الفاتحDeviceConfigurationOverride.FontScale()
: لإلغاء مقياس الخط للنظامDeviceConfigurationOverride.FontWeightAdjustment()
: لإلغاء تعديل عرض الخط في النظامDeviceConfigurationOverride.ForcedSize()
: يفرض هذا الخيار مقدارًا محددًا من المساحة بغض النظر عن حجم الجهاز.DeviceConfigurationOverride.LayoutDirection()
: لإلغاء اتجاه التنسيق (من اليسار إلى اليمين أو من اليمين إلى اليسار).DeviceConfigurationOverride.Locales()
: لإلغاء اللغةDeviceConfigurationOverride.RoundScreen()
: يلغي هذا الخيار إذا كانت الشاشة مستديرة.
لتطبيق خيار إلغاء معيّن، عليك لف المحتوى الذي يخضع للاختبار في استدعاء وظيفة المستوى الأعلى في DeviceConfigurationOverride()
، لتمرير عملية الإلغاء لكي يتم تطبيقها كمَعلمة.
على سبيل المثال، يُطبِّق الرمز التالي خطأ DeviceConfigurationOverride.ForcedSize()
لتغيير الكثافة محليًا، ما يؤدي إلى عرض عنصر MyScreen
القابل للإنشاء في نافذة أفقية كبيرة، حتى إذا كان الجهاز الذي يتم إجراء الاختبار عليه لا يتوافق مع حجم النافذة مباشرةً:
composeTestRule.setContent { DeviceConfigurationOverride( DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp)) ) { MyScreen() // will be rendered in the space for 1280dp by 800dp without clipping } }
لتطبيق عمليات إلغاء متعددة معًا، استخدِم
DeviceConfigurationOverride.then()
:
composeTestRule.setContent { DeviceConfigurationOverride( DeviceConfigurationOverride.FontScale(1.5f) then DeviceConfigurationOverride.FontWeightAdjustment(200) ) { Text(text = "text with increased scale and weight") } }
مراجع إضافية
- اختبار التطبيقات على Android: توفر الصفحة المقصودة لاختبار تطبيقات Android نظرة أوسع عن أساسيات الاختبار وتقنياته.
- أساسيات الاختبار: تعرَّف على مزيد من المعلومات حول المفاهيم الأساسية لاختبار تطبيق Android.
- الاختبارات المحلية: يمكنك إجراء بعض الاختبارات محليًا، في محطة عملك الخاصة.
- الاختبارات الموجَّهة: من الممارسات الجيدة أيضًا إجراء الاختبارات الموجَّهة. أي، الاختبارات التي يتم إجرائها مباشرةً على الجهاز.
- الدمج المستمر: يتيح لك الدمج المستمر دمج اختباراتك في مسار النشر.
- اختبار أحجام الشاشات المختلفة: في ظل توفّر بعض الأجهزة للمستخدمين، عليك اختبار أحجام الشاشات المختلفة.
- Espresso: على الرغم من أنّها مخصّصة لواجهات المستخدم المستندة إلى العرض، إلا أن الإلمام بقهوة Espresso يمكن أن يكون مفيدًا في بعض جوانب اختبار Compose.