التحكُّم في تطبيقك من خلال "مقاييس الأداء التقريبية"

على عكس معظم اختبارات واجهة مستخدم Android، يتم تشغيل اختبارات Macrobenchmark في عملية منفصلة عن التطبيق نفسه. وهذا ضروري لتفعيل إجراءات مثل إيقاف عملية التطبيق والترجمة من رمز DEX الثانوي إلى رمز الآلة.

يمكنك التحكّم في حالة تطبيقك باستخدام مكتبة UIAutomator أو آليات أخرى يمكنها التحكّم في التطبيق المستهدَف من عملية الاختبار. لعرض عناصر Compose على UI Automator، استخدِم Modifier.testTag.

يستخدِم المثال التالي LazyColumn مع testTag:

@Composable
fun ProductListScreen() {
    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .testTag("my_lazy_column")    ) {
        items(100) { index ->
            ProductItem(index)
        }
    }
}

يستخدِم الاختبار testTag للعثور على LazyColumn وتمريره سريعًا:

@Test
fun scrollList() {
    benchmarkRule.measureRepeated(
        packageName = "com.example.myapp",
        metrics = listOf(FrameTimingMetric()),
        iterations = 5,
        setupBlock = {
            uiAutomator {
                pressHome()
                startApp("com.example.myapp")
            }
        }
    ) {
        uiAutomator {
            // Find the Composable using its testTag mapped as a viewIdResourceName
            val lazyColumn = onElement { viewIdResourceName == "my_lazy_column" }

            // Fling the Compose list down
            repeat(3) {
                lazyColumn.fling(Direction.DOWN)
            }
        }
    }
}

ليس من الضروري أن يمرّر اختبار الأداء واجهة المستخدم سريعًا. بدلاً من ذلك، يمكنه تشغيل رسم متحرك مثلاً. وليس من الضروري أيضًا استخدام UI Automator تحديدًا. يجمع الاختبار مقاييس الأداء طالما يتم إنتاج الإطارات.

في بعض الأحيان، قد تريد قياس أداء شاشة معيّنة لا تظهر على الفور عند بدء تشغيل التطبيق، مثل شاشة التفاصيل أو صفحة الدفع في مكان معيّن ضمن رسم Jetpack Navigation البياني.

بما أنّ Macrobenchmark يتم تشغيله خارج العملية، لا يمكنك التفاعل مباشرةً مع NavController لتبديل الشاشات. بدلاً من ذلك، يجب أن يحاكي اختبار الأداء مستخدمًا ينتقل إلى هذا الجزء من التطبيق.

استخدِم setupBlock للتعامل مع خطوات الإعداد، مثل النقر على مسار إعداد أو زر قائمة. بهذه الطريقة، لا تسجِّل measureBlock سوى مقاييس الأداء للشاشة المستهدَفة فقط.

@Test
fun deepScreenScrollList() {
    benchmarkRule.measureRepeated(
        packageName = "com.example.myapp",
        metrics = listOf(FrameTimingMetric()),
        iterations = 5,
        setupBlock = {
            uiAutomator {
                // 1. Start the app on the home screen
                startApp("com.example.myapp")

                // 2. Navigate to the internal screen by clicking a Compose component
                // (e.g., a card that opens the target list view)
                val settingsButton = onElement { viewIdResourceName == "go_to_list_button" }
                settingsButton.click()

                // 3. Wait until the target screen settles and is fully rendered
                waitForStableInActiveWindow()
            }
        }
    ) {
        uiAutomator {
            // The actual benchmark measurement starts here on the target screen
            val lazyColumn = onElement { viewIdResourceName == "my_lazy_column" }
            lazyColumn.fling(Direction.DOWN)
        }
    }
}

مراجع إضافية

لمزيد من المعلومات عن الاختبار، اطّلِع على المراجع التالية.

الوثائق

محتوى "طرق العرض"