সাধারণ প্যাটার্ন

আপনি সুপ্রতিষ্ঠিত পদ্ধতি ও প্যাটার্ন ব্যবহার করে Compose অ্যাপ পরীক্ষা করতে পারেন।

আলাদাভাবে পরীক্ষা করা

ComposeTestRule আপনাকে কোনও কম্পোজ করার উপযুক্ত আইটেম দেখানোর মাধ্যমে অ্যাক্টিভিটি শুরু করতে দেয়: আপনার সম্পূর্ণ অ্যাপ্লিকেশন, একটি স্ক্রিন বা একটি ছোট এলিমেন্ট। এছাড়াও, আপনার কম্পোজেবল সঠিকভাবে এনক্যাপসুলেট করা আছে কিনা এবং সেগুলি স্বতন্ত্রভাবে কাজ করে কিনা তা চেক করা একটি ভাল প্র্যাক্টিস। এটি আরও সহজ এবং আরও ফোকাসড UI টেস্টিং করতে সাহায্য করে।

এর অর্থ এই নয় যে আপনাকে শুধুমাত্র ইউনিট UI টেস্ট তৈরি করতে হবে। UI টেস্টের স্কোপিং আপনার UI-এর বৃহত্তর অংশও খুব গুরুত্বপূর্ণ।

আপনার নিজের কন্টেন্ট সেট করার পরে অ্যাক্টিভিটি ও রিসোর্স অ্যাক্সেস করা

অনেক সময় আপনাকে composeTestRule.setContent ব্যবহার করে পরীক্ষা করা কন্টেন্ট সেট করতে হয় এবং আপনাকে অ্যাক্টিভিটি রিসোর্সও অ্যাক্সেস করতে হয়, যেমন প্রদর্শিত টেক্সট যে স্ট্রিং রিসোর্সের সাথে ম্যাচ করছে তা নিশ্চিত করতে। তবে, অ্যাক্টিভিটি যদি আগেই 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 হল একটি শুধুমাত্র-পরীক্ষার API যা আপনাকে পরীক্ষার অধীনে থাকা @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")
    }
}

পরীক্ষায় কাস্টম ব্যর্থতা ম্যানেজ করা

UI টেস্ট ডিবাগ করার জন্য প্রায়শই স্ক্রিন স্টেট ও কম্পোজিশন হায়ারার্কি পরীক্ষা করতে হয় যখন কোনও অ্যাসারশন ব্যর্থ হয়।

ডায়াগনস্টিকসকে আরও সহজ করে তুলতে, Compose-এ একটি নেটিভ ব্যর্থতা ম্যানেজ করার পাইপলাইন থাকে। আপনি ব্যর্থতার পরে অটোমেটিক স্ক্রিনশট ও UI হায়ারার্কি ক্যাপচার করতে পারেন অথবা ক্র্যাশ টেলিমেট্রি এক্সটার্নাল টুলে ফরওয়ার্ড করার জন্য কাস্টম হ্যান্ডলার রেজিস্টার করতে পারেন।

ব্যর্থতা ম্যানেজ করা কনফিগার করা

ব্যর্থতা ম্যানেজ করার বিষয়টি কনফিগার করতে, TestFailurePolicy অবজেক্টটি ComposeUiTestConfig-এ পাস করুন।

বিল্ট-ইন সমস্যা সংক্রান্ত আর্টিফ্যাক্ট ক্যাপচার করা

পরীক্ষা ব্যর্থ হলে স্ক্রিনশট ও UI হায়ারার্কি ক্যাপচার করতে, 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 এবং স্যুট-লেভেল রানার আর্গুমেন্ট, দুটিই মূল্যায়ন করে:

  • আপনার টেস্টে CaptureMode.Enabled/Disabled মোড স্পষ্টভাবে সেট করলেfailurePolicy, এটি রানার আর্গুমেন্টকে ওভাররাইড করে।
  • আপনি কোনও মোড CaptureMode.Unspecified হিসেবে সেট করলে (অথবা failurePolicy-কে null হিসেবে রেখে দিলে), ফ্রেমওয়ার্ক রানার আর্গুমেন্টে ফল ব্যাক করে।

অতিরিক্ত রিসোর্স

  • Android-এ অ্যাপ পরীক্ষা করা: মূল Android টেস্টিং ল্যান্ডিং পৃষ্ঠা থেকে টেস্টিংয়ের মৌলিক বিষয় ও টেকনিক সম্পর্কে আরও বিস্তারিত জানা যায়।
  • টেস্টিংয়ের মূল বিষয়: Android অ্যাপ টেস্টিংয়ের পেছনের মূল কনসেপ্ট সম্পর্কে আরও জানুন।
  • লোকাল টেস্ট: আপনি নিজের ওয়ার্কস্টেশনে লোকাল কিছু টেস্ট চালাতে পারেন।
  • ইনস্ট্রুমেন্টেড টেস্ট: ইনস্ট্রুমেন্টেড টেস্ট রান করাও ভালো প্র্যাক্টিস। অর্থাৎ, সরাসরি ডিভাইসে রান করা টেস্ট।
  • অবিরাম ইন্টিগ্রেশন: অবিরাম ইন্টিগ্রেশন আপনাকে ডিপ্লয়মেন্ট পাইপলাইনে আপনার পরীক্ষা ইন্টিগ্রেট করতে দেয়।
  • আলাদা আলাদা স্ক্রিন সাইজ টেস্ট করুন: ব্যবহারকারীদের জন্য অনেক ডিভাইস উপলভ্য থাকার কারণে, আপনাকে আলাদা আলাদা স্ক্রিন সাইজ টেস্ট করতে হবে।
  • Espresso: ভিউ-ভিত্তিক UI-এর জন্য তৈরি করা হলেও, Espresso সংক্রান্ত জ্ঞান এখনও Compose টেস্টিংয়ের কিছু দিক থেকে সহায়ক হতে পারে।