सामान्य पैटर्न

Compose ऐप्लिकेशन को, अच्छी तरह से स्थापित किए गए तरीकों और पैटर्न के हिसाब से टेस्ट किया जा सकता है.

अलग से टेस्ट करना

ComposeTestRule की मदद से, कोई भी कंपोज़ेबल दिखाया जा सकता है. जैसे: आपका पूरा ऐप्लिकेशन, कोई एक स्क्रीन या कोई छोटा एलिमेंट. यह भी एक अच्छा तरीका है कि आप यह जांच करें कि आपके कंपोज़ेबल सही तरीके से इनकैप्सुलेट किए गए हैं और वे स्वतंत्र रूप से काम करते हैं. इससे यूज़र इंटरफ़ेस (यूआई) की टेस्टिंग आसानी से और ज़्यादा फ़ोकस के साथ की जा सकती है.

इसका मतलब यह नहीं है कि आपको सिर्फ़ यूनिट यूज़र इंटरफ़ेस (यूआई) टेस्ट बनाने चाहिए. यूज़र इंटरफ़ेस (यूआई) के बड़े हिस्सों की जांच करने वाले यूआई टेस्ट भी बहुत ज़रूरी होते हैं.

अपना कॉन्टेंट सेट करने के बाद, गतिविधि और संसाधनों को ऐक्सेस करना

अक्सर आपको composeTestRule.setContent का इस्तेमाल करके, टेस्ट किए जा रहे कॉन्टेंट को सेट करना होता है. साथ ही, आपको गतिविधि के संसाधनों को भी ऐक्सेस करना होता है. उदाहरण के लिए, यह पुष्टि करने के लिए कि दिखाया गया टेक्स्ट, स्ट्रिंग रिसॉर्स से मेल खाता है. हालांकि, अगर गतिविधि पहले से ही को कॉल करती है, तो createAndroidComposeRule() का इस्तेमाल करके बनाए गए नियम पर setContent को कॉल नहीं किया जा सकता.

इसके लिए, ComponentActivity जैसी खाली गतिविधि का इस्तेमाल करके, AndroidComposeTestRule बनाया जाता है.

class MyComposeTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule<ComponentActivity>()

    @Test
    fun myTest() {
        // Start the app
        composeTestRule.setContent {
            MyAppTheme {
                MainScreen(uiState = exampleUiState, /*...*/)
            }
        }
        val continueLabel = composeTestRule.activity.getString(R.string.next)
        composeTestRule.onNodeWithText(continueLabel).performClick()
    }
}

ध्यान दें कि ComponentActivity को आपके ऐप्लिकेशन की AndroidManifest.xml फ़ाइल में जोड़ना होगा. इसे चालू करने के लिए, अपने मॉड्यूल में यह डिपेंडेंसी जोड़ें:

debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")

कस्टम सिमैंटिक्स प्रॉपर्टी

टेस्ट में जानकारी दिखाने के लिए, कस्टम सिमैंटिक्स प्रॉपर्टी बनाई जा सकती हैं. इसके लिए, एक नया SemanticsPropertyKey तय करें और इसे SemanticsPropertyReceiver का इस्तेमाल करके उपलब्ध कराएं.

// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey

अब उस प्रॉपर्टी का इस्तेमाल semantics मॉडिफ़ायर में करें:

val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
    modifier = Modifier.semantics { pickedDate = datePickerValue }
)

जांचों में, प्रॉपर्टी की वैल्यू की पुष्टि करने के लिए SemanticsMatcher.expectValue का इस्तेमाल करें:

composeTestRule
    .onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
    .assertExists()

स्टेट को वापस लाने की पुष्टि करना

पुष्टि करें कि गतिविधि या प्रोसेस को फिर से बनाए जाने पर, आपके कंपोज़ एलिमेंट की स्थिति सही तरीके से वापस आ गई हो. StateRestorationTester क्लास की मदद से, गतिविधि को फिर से बनाने की ज़रूरत के बिना ऐसी जांच करें.

इस क्लास की मदद से, कंपोज़ेबल को फिर से बनाने का सिम्युलेशन किया जा सकता है. यह rememberSaveable को लागू करने की पुष्टि करने के लिए खास तौर पर उपयोगी है.


class MyStateRestorationTests {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun onRecreation_stateIsRestored() {
        val restorationTester = StateRestorationTester(composeTestRule)

        restorationTester.setContent { MainScreen() }

        // TODO: Run actions that modify the state

        // Trigger a recreation
        restorationTester.emulateSavedInstanceStateRestore()

        // TODO: Verify that state has been correctly restored.
    }
}

अलग-अलग डिवाइस कॉन्फ़िगरेशन की जांच करना

Android ऐप्लिकेशन को कई बदलती स्थितियों के हिसाब से ढलना पड़ता है. जैसे, विंडो का साइज़, स्थान-भाषा, फ़ॉन्ट का साइज़, गहरे और हल्के रंग वाली थीम वगैरह. इनमें से ज़्यादातर शर्तें, डिवाइस-लेवल की वैल्यू से तय होती हैं. इन वैल्यू को उपयोगकर्ता कंट्रोल करता है और ये मौजूदा Configuration इंस्टेंस के साथ दिखती हैं. टेस्ट में अलग-अलग कॉन्फ़िगरेशन की जांच करना मुश्किल होता है, क्योंकि टेस्ट को डिवाइस-लेवल की प्रॉपर्टी कॉन्फ़िगर करनी होती हैं.

DeviceConfigurationOverride सिर्फ़ टेस्टिंग के लिए उपलब्ध एपीआई है. इसकी मदद से, टेस्ट किए जा रहे @Composable कॉन्टेंट के लिए, अलग-अलग डिवाइस कॉन्फ़िगरेशन को स्थानीय भाषा में सिम्युलेट किया जा सकता है.

DeviceConfigurationOverride के कंपैनियन ऑब्जेक्ट में ये एक्सटेंशन फ़ंक्शन होते हैं. ये डिवाइस-लेवल के कॉन्फ़िगरेशन की प्रॉपर्टी को बदल देते हैं:

किसी खास बदलाव को लागू करने के लिए, जांच किए जा रहे कॉन्टेंट को DeviceConfigurationOverride() टॉप-लेवल फ़ंक्शन के कॉल में रैप करें. साथ ही, लागू किए जाने वाले बदलाव को पैरामीटर के तौर पर पास करें.

उदाहरण के लिए, यहां दिए गए कोड में DeviceConfigurationOverride.ForcedSize() ओवरराइड का इस्तेमाल करके, डेंसिटी को स्थानीय तौर पर बदला गया है. इससे MyScreen कंपोज़ेबल को बड़े लैंडस्केप विंडो में रेंडर किया जा सकेगा. भले ही, जिस डिवाइस पर टेस्ट चल रहा है वह सीधे तौर पर उस विंडो के साइज़ के साथ काम न करता हो:

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
    }
}

एक साथ कई ओवरराइड लागू करने के लिए, DeviceConfigurationOverride.then() का इस्तेमाल करें:

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.FontScale(1.5f) then
            DeviceConfigurationOverride.FontWeightAdjustment(200)
    ) {
        Text(text = "text with increased scale and weight")
    }
}

टेस्ट में गड़बड़ी होने पर, उसे पसंद के मुताबिक हैंडल करना

यूज़र इंटरफ़ेस (यूआई) टेस्ट को डीबग करने के लिए, अक्सर स्क्रीन की स्थिति और कंपोज़िशन हायरार्की की जांच करनी पड़ती है. ऐसा तब होता है, जब कोई दावा पूरा नहीं होता.

Compose, गड़बड़ी ठीक करने के लिए नेटिव पाइपलाइन उपलब्ध कराता है, ताकि डाइग्नोस्टिक्स को बेहतर बनाया जा सके. टेस्ट के फ़ेल होने पर, स्क्रीनशॉट और यूज़र इंटरफ़ेस (यूआई) के क्रम अपने-आप कैप्चर किए जा सकते हैं. इसके अलावा, क्रैश टेलीमेट्री को बाहरी टूल पर फ़ॉरवर्ड करने के लिए, कस्टम हैंडलर रजिस्टर किए जा सकते हैं.

डेटा ट्रांसफ़र में गड़बड़ी होने पर कार्रवाई करने की सुविधा कॉन्फ़िगर करना

फ़ेल होने की स्थिति को मैनेज करने के लिए, TestFailurePolicy ऑब्जेक्ट को ComposeUiTestConfig में पास करें.

पहले से मौजूद गड़बड़ी वाले आर्टफ़ैक्ट कैप्चर करना

टेस्ट के पूरा न होने पर स्क्रीनशॉट और यूज़र इंटरफ़ेस (यूआई) के क्रम कैप्चर करने के लिए, TestFailurePolicy में screenshotCaptureMode और uiHierarchyCaptureMode प्रॉपर्टी सेट करें.

class MyComposeTest {
    private val customConfig = ComposeUiTestConfig(
        failurePolicy = TestFailurePolicy(
            screenshotCaptureMode = TestFailurePolicy.CaptureMode.Enabled,
            uiHierarchyCaptureMode = TestFailurePolicy.CaptureMode.Enabled
        )
    )

    @Test
    fun myFirstTest() = runComposeUiTest(config = customConfig) {
        // ...
    }
}

कस्टम फ़ेलियर हैंडलर का इस्तेमाल करना

टेस्ट फ़ेल होने पर कस्टम व्यवहार तय करने के लिए, failureHandlers सूची में TestFailureHandler जोड़ें. हर हैंडलर को एक FailureContext ऑब्जेक्ट मिलता है. इसमें ओरिजनल गड़बड़ी और पाइपलाइन के पिछले हैंडलर से जनरेट किए गए आर्टफ़ैक्ट की सूची होती है.

class MyComposeTestWithHandler {
    private val customConfig = ComposeUiTestConfig(
        failurePolicy = TestFailurePolicy(
            screenshotCaptureMode = TestFailurePolicy.CaptureMode.Enabled,
            failureHandlers = listOf(
                TestFailureHandler { context ->
                    val screenshot = context.artifacts.firstOrNull {
                        it.type == FailureArtifact.Type.Screenshot
                    }
                    // ...
                }
            )
        )
    )

    @get:Rule
    val rule = createComposeRule(config = customConfig)

    // ...
}

पूरी टेस्ट सुइट के लिए कैप्चर कॉन्फ़िगर करना

अपनी टेस्ट सुइट के लिए, फ़ेल होने वाले आर्टफ़ैक्ट कैप्चर करने की सुविधा चालू की जा सकती है. इसके लिए, अपने मॉड्यूल की build.gradle फ़ाइल में इंस्ट्रुमेंटेशन रनर के आर्ग्युमेंट पास करें. इससे अलग-अलग टेस्ट फ़ाइलों को अपडेट करने की ज़रूरत नहीं पड़ती.

// build.gradle.kts
android {
    defaultConfig {
        // ...
        testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isUiHierarchyCaptureEnabled"] = "true"
        testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isScreenshotCaptureEnabled"] = "true"
    }
}

कॉन्फ़िगरेशन लागू होने का क्रम

यह फ़्रेमवर्क, लोकल TestFailurePolicy और सुइट-लेवल, दोनों तरह के रनर आर्ग्युमेंट का आकलन करता है:

  • अगर आपने अपने टेस्ट failurePolicy में CaptureMode.Enabled/Disabled मोड को साफ़ तौर पर सेट किया है, तो यह रनर के तर्क को बदल देगा.
  • अगर आपने मोड को CaptureMode.Unspecified पर सेट किया है या failurePolicy को null के तौर पर छोड़ दिया है, तो फ़्रेमवर्क, रनर आर्ग्युमेंट पर वापस आ जाता है.

अतिरिक्त संसाधन

  • Android पर ऐप्लिकेशन की टेस्टिंग: Android टेस्टिंग के मुख्य लैंडिंग पेज पर, टेस्टिंग की बुनियादी बातों और तकनीकों के बारे में ज़्यादा जानकारी मिलती है.
  • टेस्टिंग की बुनियादी बातें: Android ऐप्लिकेशन की टेस्टिंग से जुड़े मुख्य कॉन्सेप्ट के बारे में ज़्यादा जानें.
  • लोकल टेस्ट: कुछ टेस्ट, अपने वर्कस्टेशन पर स्थानीय तौर पर किए जा सकते हैं.
  • इंस्ट्रुमेंटेड टेस्ट: इंस्ट्रुमेंटेड टेस्ट भी चलाएं. इसका मतलब है कि ऐसे टेस्ट जो सीधे तौर पर डिवाइस पर चलते हैं.
  • लगातार इंटिग्रेशन: लगातार इंटिग्रेशन की मदद से, अपने टेस्ट को डिप्लॉयमेंट पाइपलाइन में इंटिग्रेट किया जा सकता है.
  • अलग-अलग स्क्रीन साइज़ के लिए टेस्ट करें: उपयोगकर्ताओं के लिए कई तरह के डिवाइस उपलब्ध हैं. इसलिए, आपको अलग-अलग स्क्रीन साइज़ के लिए टेस्ट करना चाहिए.
  • Espresso: इसे व्यू पर आधारित यूज़र इंटरफ़ेस (यूआई) के लिए बनाया गया है. हालांकि, Espresso की जानकारी, Compose की टेस्टिंग के कुछ पहलुओं के लिए अब भी मददगार हो सकती है.