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

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

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

عند مزامنة اختبار، يتطور تطبيق 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)

مراجع غير نشِطة لفترة قصيرة

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

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

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

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

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

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

تنتظر الدالة 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.