يمكنك اختبار تطبيق 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()
التحقّق من استعادة الحالة
تأكَّد من استعادة حالة عناصر الإنشاء بشكل صحيح عند إعادة إنشاء
النشاط أو العملية. يمكنك إجراء عمليات التحقّق هذه بدون الاعتماد على
إعادة إنشاء النشاط باستخدام فئة 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()
override لتغيير الكثافة محليًا، ما يجبر العنصر القابل للتجميع MyScreen
على العرض في نافذة DeviceConfigurationOverride.ForcedSize()
عمودية كبيرة، حتى إذا كان الجهاز الذي يتم تشغيل الاختبار عليه لا يتيح حجم النافذة هذا مباشرةً:
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 مخصّص لواجهات مستنِدة إلى الاطّلاع، يمكن أن تكون المعرفة به مفيدة لبعض جوانب اختبار ميزة "الإنشاء".