اختبار أنشطة تطبيقاتك

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

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

على وجه الخصوص، من المهم التأكّد من أنّ نشاطك يتصرف بشكل صحيح استجابةً للأحداث الموضّحة في دورة حياة النشاط.

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

تحديد حالة النشاط

يتضمّن أحد الجوانب الرئيسية لاختبار أنشطة تطبيقك وضع أنشطة تطبيقك في حالات معيّنة. لتحديد الجزء "المعطى" من اختباراتك، استخدِم مثيلات ActivityScenario، وهي جزء من مكتبة AndroidX Test. باستخدام هذه الفئة، يمكنك وضع نشاطك في حالات تحاكي الأحداث على مستوى الجهاز.

ActivityScenario هي واجهة برمجة تطبيقات متوافقة مع عدّة منصات يمكنك استخدامها في اختبارات الوحدات المحلية واختبارات التكامل على الأجهزة. على جهاز حقيقي أو افتراضي، توفّر ActivityScenario أمان سلاسل التنفيذ، وتتم مزامنة الأحداث بين سلسلة تنفيذ أدوات الاختبار وسلسلة التنفيذ التي تشغّل النشاط قيد الاختبار.

تتلاءم واجهة برمجة التطبيقات هذه بشكل خاص مع تقييم طريقة عمل نشاط قيد الاختبار عند إيقافه أو إنشائه. يعرض هذا القسم حالات الاستخدام الأكثر شيوعًا المرتبطة بواجهة برمجة التطبيقات هذه.

إنشاء نشاط

لإنشاء النشاط قيد الاختبار، أضِف الرمز البرمجي الموضّح في المقتطف التالي:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
       launchActivity<MyActivity>().use {
       }
    }
}

بعد إنشاء النشاط، تنقل ActivityScenario النشاط إلى الحالة RESUMED. تشير هذه الحالة إلى أنّ نشاطك قيد التشغيل ويظهر للمستخدمين. في هذه الحالة، يمكنك التفاعل مع عناصر View النشاط باستخدام اختبارات واجهة المستخدم في Espresso.

تنصح Google باستدعاء close في النشاط عند اكتمال الاختبار. يؤدي ذلك إلى تنظيف الموارد المرتبطة وتحسين ثبات اختباراتك. تنفِّذ ActivityScenario Closeable، لذا يمكنك تطبيق الإضافة use أو try-with-resources في لغة برمجة Java، وذلك لإغلاق النشاط تلقائيًا.

بدلاً من ذلك، يمكنك استخدام ActivityScenarioRule لاستدعاء ActivityScenario.launch تلقائيًا قبل كل اختبار وActivityScenario.close عند إيقاف الاختبار. يوضّح المثال التالي كيفية تحديد قاعدة والحصول على مثيل لسيناريو منها:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>()

    @Test fun testEvent() {
        val scenario = activityScenarioRule.scenario
    }
}

توجيه النشاط إلى حالة جديدة

لتوجيه النشاط إلى حالة مختلفة، مثل CREATED أو STARTED، استخدِم الدالة moveToState(). يحاكي هذا الإجراء حالة يتم فيها إيقاف نشاطك أو إيقافه مؤقتًا، على التوالي، بسبب مقاطعة تطبيق آخر أو إجراء نظام له.

يظهر مثال على استخدام moveToState() في مقتطف الرمز التالي:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.moveToState(State.CREATED)
        }
    }
}

تحديد حالة النشاط الحالية

لتحديد الحالة الحالية لنشاط قيد الاختبار، احصل على قيمة الحقل state ضمن العنصر ActivityScenario. ويكون من المفيد بشكل خاص التحقّق من حالة نشاط قيد الاختبار إذا كان النشاط يعيد التوجيه إلى نشاط آخر أو ينهي نفسه، كما هو موضّح في مقتطف الرمز التالي:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.onActivity { activity ->
              startActivity(Intent(activity, MyOtherActivity::class.java))
            }

            val originalActivityState = scenario.state
        }
    }
}

إعادة إنشاء النشاط

عندما تكون موارد الجهاز منخفضة، قد يوقف النظام نشاطًا ما، ما يتطلّب من تطبيقك إعادة إنشاء هذا النشاط عندما يعود المستخدم إلى تطبيقك. لمحاكاة هذه الحالات، استخدِم الأمر recreate():

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.recreate()
        }
    }
}

يحتفظ صف ActivityScenario بحالة المثيل المحفوظ للنشاط وأي عناصر تم وضع تعليقات توضيحية عليها باستخدام @NonConfigurationInstance. يتم تحميل هذه العناصر في مثيل جديد للنشاط قيد الاختبار.

استرداد نتائج النشاط

للحصول على رمز النتيجة أو البيانات المرتبطة بنشاط مكتمل، احصل على قيمة الحقل result ضمن العنصر ActivityScenario، كما هو موضّح في مقتطف الرمز التالي:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testResult() {
        launchActivity<MyActivity>().use {
            onView(withId(R.id.finish_button)).perform(click())

            // Activity under test is now finished.

            val resultCode = scenario.result.resultCode
            val resultData = scenario.result.resultData
        }
    }
}

إجراءات التشغيل في النشاط

جميع الطرق ضِمن ActivityScenario هي عمليات حظر، لذا تتطلّب واجهة برمجة التطبيقات منك تنفيذها في سلسلة تعليمات الأجهزة.

لتنفيذ إجراءات في نشاطك قيد الاختبار، استخدِم أدوات مطابقة العرض في Espresso للتفاعل مع العناصر في طريقة العرض:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use {
            onView(withId(R.id.refresh)).perform(click())
        }
    }
}

إذا كنت بحاجة إلى استدعاء طريقة في النشاط نفسه، يمكنك إجراء ذلك بأمان من خلال تنفيذ ActivityAction:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.onActivity { activity ->
              activity.handleSwipeToRefresh()
            }
        }
    }
}