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

تتم مزامنة اختبارات إنشاء المحتوى تلقائيًا مع واجهة المستخدم. عند استدعاء تأكيد أو إجراء باستخدام 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() أن يكون Compose غير نشِط، ولكن تعتمد الدالة على السمة 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 يمكن أن تكون مفيدة لبعض جوانب اختبار Compose.