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

تتم مزامنة إنشاء الاختبارات مع واجهة المستخدم بشكل تلقائي. عند طلب تأكيد أو إجراء باستخدام 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()
}

تجدر الإشارة إلى أنّ هذا الشرط لا ينطبق إلا على هيكلية Compose وليس على بقية التطبيق.

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

عند طلب تأكيد أو إجراء من خلال 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)

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

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

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