ইন্টারঅপারেবিলিটি

কম্পোজ প্রচলিত টেস্টিং ফ্রেমওয়ার্কগুলোর সাথে সমন্বিত হয়।

এসপ্রেসোর সাথে আন্তঃকার্যক্ষমতা

একটি হাইব্রিড অ্যাপে, আপনি ভিউ হায়ারার্কির ভিতরে কম্পোজ কম্পোনেন্ট এবং কম্পোজ কম্পোজেবলের ভিতরে ভিউ খুঁজে পেতে পারেন ( AndroidView কম্পোজেবলের মাধ্যমে)।

উভয় প্রকার মেলানোর জন্য কোনো বিশেষ পদক্ষেপের প্রয়োজন নেই। আপনি Espresso-এর onView ব্যবহার করে ভিউ এবং ComposeTestRule ব্যবহার করে কম্পোজ এলিমেন্ট মেলান।

@Test
fun androidViewInteropTest() {
    // Check the initial state of a TextView that depends on a Compose state.
    Espresso.onView(withText("Hello Views")).check(matches(isDisplayed()))
    // Click on the Compose button that changes the state.
    composeTestRule.onNodeWithText("Click here").performClick()
    // Check the new value.
    Espresso.onView(withText("Hello Compose")).check(matches(isDisplayed()))
}

কম্পোজ ইন্টারঅপ টেস্টিং-এর জন্য ভিউ-স্কোপড সিম্যান্টিকস যোগ করুন

স্কোপ কম্পোজ সার্চকে নির্দিষ্ট ভিউতে সীমাবদ্ধ করে।

জটিল UI-গুলিকে Compose-এ স্থানান্তর করার সময়, আপনি একাধিক প্রচলিত Android View-এর ভিতরে একই রকম Compose এলিমেন্ট দেখতে পারেন—যেমন একটি RecyclerView বা ViewPager মধ্যে। এই পরিস্থিতিতে, onNodeWithText("Save") এর মতো একটি সাধারণ Compose সার্চ "Multiple nodes found" ত্রুটির কারণে ব্যর্থ হতে পারে।

এই উপাদানগুলোকে আলাদা করার জন্য ডাইনামিক টেস্ট ট্যাগ যুক্ত করতে আপনার প্রোডাকশন কোড পরিবর্তন করার পরিবর্তে, আপনি সরাসরি একটি নির্দিষ্ট অ্যান্ড্রয়েড ভিউতে আপনার কম্পোজ টেস্টকে সীমাবদ্ধ করতে পারেন।

আপনার টেস্ট রুলে onRootWithViewInteraction API ব্যবহার করুন। এই ফাংশনটি একটি Espresso ViewInteraction গ্রহণ করে, যা আপনাকে Espresso ব্যবহার করে একটি নির্দিষ্ট কন্টেইনার ভিউকে আলাদা করতে এবং শুধুমাত্র সেই নির্দিষ্ট হায়ারার্কির মধ্যেই Compose ইন্টারঅ্যাকশন সম্পাদন করতে সাহায্য করে।

তালিকার কোনো আইটেমের সাথে ইন্টারঅ্যাক্ট করুন

যদি আপনাকে একটি নির্দিষ্ট RecyclerView সারির ভিতরে থাকা কোনো Compose এলিমেন্টের সাথে ইন্টারঅ্যাক্ট করতে হয়, তাহলে Espresso ব্যবহার করে সারিটি সনাক্ত করুন এবং তারপর আপনার Compose ইন্টারঅ্যাকশনটিকে সেটির মধ্যেই সীমাবদ্ধ রাখুন। এর ফলে অন্য সব সারিতে থাকা একই ধরনের Compose এলিমেন্টগুলো উপেক্ষা করা হবে।

@Test
fun testComposeButtonInsideRecyclerViewItem() = runComposeUiTest {
    // Scroll to the desired position using Espresso
    Espresso.onView(withId(recyclerViewId))
        .perform(RecyclerViewActions.scrollToPosition<MyViewHolder>(3))

    // Define an Espresso ViewInteraction that uniquely identifies the row
    val rowView = Espresso.onView(
        allOf(
            withId(rootViewId),
            hasDescendant(withText("Item #3"))
        )
    )

    // Scope the Compose search strictly to that specific row View
    onRootWithViewInteraction(rowView)
        .onNode(hasText("Like"))
        .performClick()
}

ভিউপেজারগুলিতে অস্পষ্টতা দূর করুন

যখন একই কম্পোজ লেআউট সহ একাধিক ফ্র্যাগমেন্ট একই সাথে মেমরিতে থাকে, তখন মিল সংক্রান্ত অস্পষ্টতা এড়াতে আপনি নির্দিষ্ট ফ্র্যাগমেন্টের রুট ভিউ আইডিতে অনুসন্ধানটি সীমাবদ্ধ করতে পারেন।

@Test
fun testComposeButtonInsideViewPagerItem() = runComposeUiTest {
    // Swipe to the desired page using Espresso
    Espresso.onView(withId(viewPagerViewId)).perform(swipeLeft())

    // Identify the specific container view using Espresso
    val fragmentB = Espresso.onView(withId(fragmentRootViewId))

    // The generic text "Save" is now unique within this view scope
    onRootWithViewInteraction(fragmentB)
        .onNode(hasText("Save"))
        .assertIsDisplayed()
}

UiAutomator-এর সাথে আন্তঃকার্যক্ষমতা

ডিফল্টরূপে, কম্পোজেবলগুলো UiAutomator থেকে শুধুমাত্র তাদের সুবিধাজনক ডেসক্রিপ্টর (প্রদর্শিত টেক্সট, কন্টেন্ট ডেসক্রিপশন, ইত্যাদি) দ্বারা অ্যাক্সেসযোগ্য। আপনি যদি Modifier.testTag ব্যবহার করে এমন কোনো কম্পোজেবল অ্যাক্সেস করতে চান, তাহলে আপনাকে নির্দিষ্ট কম্পোজেবলটির সাবট্রি-এর জন্য testTagsAsResourceId নামক সিম্যান্টিক প্রপার্টিটি এনাবল করতে হবে। এই আচরণটি এনাবল করা সেইসব কম্পোজেবলের জন্য উপযোগী যাদের অন্য কোনো অনন্য হ্যান্ডেল নেই, যেমন স্ক্রোলযোগ্য কম্পোজেবল (উদাহরণস্বরূপ, LazyColumn )।

আপনার কম্পোজেবলস হায়ারার্কির উপরের স্তরে সিমান্টিক প্রপার্টিটি শুধুমাত্র একবার সক্রিয় করুন, যাতে Modifier.testTag সহ সমস্ত নেস্টেড কম্পোজেবলস UiAutomator থেকে অ্যাক্সেসযোগ্য হয়।

Scaffold(
    // Enables for all composables in the hierarchy.
    modifier = Modifier.semantics {
        testTagsAsResourceId = true
    }
){
    // Modifier.testTag is accessible from UiAutomator for composables nested here.
    LazyColumn(
        modifier = Modifier.testTag("myLazyColumn")
    ){
        // Content
    }
}

Modifier.testTag(tag) দিয়ে তৈরি যেকোনো কম্পোজেবল আইটেমকে, resourceName হিসেবে একই tag ব্যবহার করে By.res(resourceName) এর মাধ্যমে অ্যাক্সেস করা যায়।

val device = UiDevice.getInstance(getInstrumentation())

val lazyColumn: UiObject2 = device.findObject(By.res("myLazyColumn"))
// Some interaction with the lazyColumn.

অতিরিক্ত সম্পদ

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