مزامنة الاختبارات

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

في العادة، ليس عليك اتّخاذ أي إجراء. ومع ذلك، هناك بعض الحالات القصوى التي يجب معرفتها.

عند مزامنة اختبار، يتم تقديم تطبيق Compose في الوقت باستخدام ساعة افتراضية. وهذا يعني أنّ اختبارات Compose لا يتم إجراؤها في الوقت الفعلي، لذا يمكن أن تجتاز الاختبار بأسرع ما يمكن.

ومع ذلك، إذا لم تستخدم الطرق التي تُزامن اختباراتك، لن يتم إعادة التركيب وسيبدو أنّ واجهة المستخدم متوقفة مؤقتًا.

@Test
fun counterTest() {
    val myCounter = mutableStateOf(0) // State that can cause recompositions.
    var lastSeenValue = 0 // Used to track recompositions.
    composeTestRule.setContent {
        Text(myCounter.value.toString())
        lastSeenValue = myCounter.value
    }
    myCounter.value = 1 // The state changes, but there is no recomposition.

    // Fails because nothing triggered a recomposition.
    assertTrue(lastSeenValue == 1)

    // Passes because the assertion triggers recomposition.
    composeTestRule.onNodeWithText("1").assertExists()
}

يُرجى العِلم أنّ هذا الشرط ينطبق فقط على التسلسلات الهرميّة لميزة "الإنشاء" وليس على باقي أجزاء التطبيق.

إيقاف المزامنة التلقائية

عند استدعاء تأكيد أو إجراء من خلال ComposeTestRule مثل assertExists()، تتم مزامنة الاختبار مع واجهة مستخدم Compose. في بعض الحالات، قد تحتاج إلى إيقاف هذه المزامنة والتحكّم في الساعة بنفسك. على سبيل المثال، يمكنك التحكّم في الوقت لالتقاط لقطات شاشة دقيقة لصورة متحركة في نقطة لن تزال فيها واجهة المستخدم مشغولة. لإيقاف المزامنة التلقائية، اضبط السمة autoAdvance في mainClock على false:

composeTestRule.mainClock.autoAdvance = false

وعادةً ما يتم بعد ذلك تقديم الوقت بنفسك. يمكنك تخطّي кадр واحد بالضبط باستخدام advanceTimeByFrame() أو تخطّي مدة معيّنة باستخدام advanceTimeBy():

composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.mainClock.advanceTimeBy(milliseconds)

الموارد غير النشطة

يمكن أن تُزامن ميزة "الإنشاء" الاختبارات وواجهة المستخدم لكي يتم تنفيذ كل إجراء وتأكيد في حالة الخمول، في انتظار الساعة أو تقديمها حسب الحاجة. ومع ذلك، يمكن تنفيذ بعض العمليات غير المتزامنة التي تؤثر نتائجها في حالة واجهة المستخدم في الخلفية بدون أن يلاحظها الاختبار.

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

تتشابه واجهة برمجة التطبيقات هذه كثيرًا مع موارد الخمول في Espresso للإشارة إلى ما إذا كان العنصر الخاضع للاختبار في وضع الخمول أو مشغولاً. استخدِم قاعدة اختبار Compose لتسجيل تنفيذ IdlingResource.

composeTestRule.registerIdlingResource(idlingResource)
composeTestRule.unregisterIdlingResource(idlingResource)

المزامنة اليدوية

في بعض الحالات، عليك مزامنة واجهة مستخدم ميزة "الإنشاء" مع أجزاء أخرى من اختبارك أو التطبيق الذي تختبره.

تنتظر الدالة waitForIdle() انتهاء وضع "إنشاء"، ولكن تتعلّق الدالة بالسمة autoAdvance:

composeTestRule.mainClock.autoAdvance = true // Default
composeTestRule.waitForIdle() // Advances the clock until Compose is idle.

composeTestRule.mainClock.autoAdvance = false
composeTestRule.waitForIdle() // Only waits for idling resources to become idle.

يُرجى العلم أنّه في كلتا الحالتَين، ينتظر waitForIdle() أيضًا عمليات اجتياز رسومات وتنسيقات في انتظار المراجعة.

يمكنك أيضًا تقديم الوقت إلى أن يتم استيفاء شرط معيّن باستخدام الرمز advanceTimeUntil().

composeTestRule.mainClock.advanceTimeUntil(timeoutMs) { condition }

يُرجى العلم أنّ الشرط المحدَّد يجب أن يتحقّق من الحالة التي يمكن أن تتأثّر بهذه الساعة (لا تعمل إلا مع حالة "إنشاء").

انتظار استيفاء الشروط

أيّ شرط يعتمد على عمل خارجي، مثل تحميل البيانات أو قياس أو رسم Android (أي القياس أو الرسم الخارجيَين لـ Compose)، يجب أن يستخدم مفهومًا أكثر عمومية مثل waitUntil():

composeTestRule.waitUntil(timeoutMs) { condition }

يمكنك أيضًا استخدام أيّ من waitUntil الأدوات المساعِدة التالية:

composeTestRule.waitUntilAtLeastOneExists(matcher, timeoutMs)

composeTestRule.waitUntilDoesNotExist(matcher, timeoutMs)

composeTestRule.waitUntilExactlyOneExists(matcher, timeoutMs)

composeTestRule.waitUntilNodeCount(matcher, count, timeoutMs)

مراجع إضافية

  • اختبار التطبيقات على Android: تقدّم الصفحة المقصودة الرئيسية لاختبار Android نظرة أوسع على أساسيات الاختبار وأساليبه.
  • أساسيات الاختبار: اطّلِع على مزيد من المعلومات عن المفاهيم الأساسية لاختبار تطبيق Android.
  • الاختبارات المحلية: يمكنك إجراء بعض الاختبارات محليًا على محطة عملك.
  • الاختبارات المستندة إلى الأدوات: من الممارسات الجيدة إجراء الاختبارات المستندة إلى الأدوات أيضًا. أي الاختبارات التي يتم إجراؤها مباشرةً على الجهاز.
  • التكامل المستمر: يتيح لك التكامل المستمر دمج اختباراتك في مسار إتمام النشر.
  • اختبار أحجام الشاشة المختلفة: مع توفّر العديد من الأجهزة للمستخدمين، يجب اختبار أحجام الشاشة المختلفة.
  • Espresso: على الرغم من أنّ Espresso مخصّص لواجهات مستنِدة إلى الاطّلاع، يمكن أن تكون المعرفة به مفيدة لبعض جوانب اختبار ميزة "الإنشاء".