يمكنك اختبار تطبيق 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()
لتغيير الكثافة محليًا، ما يؤدي إلى فرض عرض عنصر 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.