বিভিন্ন স্ক্রীন মাপ পরীক্ষা করার জন্য লাইব্রেরি এবং টুল

অ্যান্ড্রয়েড বিভিন্ন ধরনের টুল এবং এপিআই প্রদান করে, যা আপনাকে বিভিন্ন স্ক্রিন ও উইন্ডোর আকারের জন্য টেস্ট তৈরি করতে সাহায্য করতে পারে।

ডিভাইস কনফিগারেশন ওভাররাইড

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

   DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
    }
চিত্র ১। DeviceConfigurationOverride ব্যবহার করে একটি ছোট আকারের ডিভাইসের মধ্যে ট্যাবলেট লেআউট স্থাপন করা, যেমনটি ‘এখন অ্যান্ড্রয়েডে’ করা যায়।

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

রোবোইলেকট্রিক

রোবোলেক্ট্রিক ব্যবহার করে স্থানীয়ভাবে JVM-এ কম্পোজ বা ভিউ-ভিত্তিক UI টেস্ট চালান — কোনো ডিভাইস বা এমুলেটরের প্রয়োজন নেই। অন্যান্য দরকারি বৈশিষ্ট্যের পাশাপাশি, আপনি নির্দিষ্ট স্ক্রিন সাইজ ব্যবহার করার জন্য রোবোলেক্ট্রিক কনফিগার করতে পারেন।

Now in Android- এর নিম্নলিখিত উদাহরণটিতে , Robolectric-কে 480 dpi রেজোলিউশন সহ 1000x1000 dp স্ক্রিন সাইজ অনুকরণ করার জন্য কনফিগার করা হয়েছে:

@RunWith(RobolectricTestRunner::class)
// Configure Robolectric to use a very large screen size that can fit all of the test sizes.
// This allows enough room to render the content under test without clipping or scaling.
@Config(qualifiers = "w1000dp-h1000dp-480dpi")
class NiaAppScreenSizesScreenshotTests { ... }

আপনি টেস্ট বডি থেকেও কোয়ালিফায়ার সেট করতে পারেন, যেমনটা 'Now in Android' উদাহরণের এই কোড স্নিপেটটিতে করা হয়েছে:

val (width, height, dpi) = ...

// Set qualifiers from specs.
RuntimeEnvironment.setQualifiers("w${width}dp-h${height}dp-${dpi}dpi")

উল্লেখ্য যে, RuntimeEnvironment.setQualifiers() নতুন কনফিগারেশন দিয়ে সিস্টেম এবং অ্যাপ্লিকেশন রিসোর্স আপডেট করে, কিন্তু সক্রিয় অ্যাক্টিভিটি বা অন্যান্য কম্পোনেন্টের উপর কোনো অ্যাকশন ট্রিগার করে না।

আপনি রোবোইলেকট্রিক ডিভাইস কনফিগারেশন ডকুমেন্টেশনে আরও বিস্তারিত পড়তে পারেন।

গ্রেডল-পরিচালিত ডিভাইস

গ্রেডল-ম্যানেজড ডিভাইস (GMD) অ্যান্ড্রয়েড গ্রেডল প্লাগইনটি আপনাকে সেইসব এমুলেটর এবং আসল ডিভাইসের স্পেসিফিকেশন নির্ধারণ করতে দেয়, যেখানে আপনার ইনস্ট্রুমেন্টেড টেস্টগুলো চলে। বিভিন্ন স্ক্রিন সাইজের ডিভাইসের জন্য স্পেসিফিকেশন তৈরি করে এমন একটি টেস্টিং কৌশল বাস্তবায়ন করুন, যেখানে নির্দিষ্ট টেস্টগুলো অবশ্যই নির্দিষ্ট স্ক্রিন সাইজে চালাতে হবে। কন্টিনিউয়াস ইন্টিগ্রেশন (CI)-এর সাথে GMD ব্যবহার করে, আপনি নিশ্চিত করতে পারেন যে প্রয়োজনের সময় সঠিক টেস্টগুলো চলছে, যা এমুলেটর প্রোভিশনিং ও লঞ্চ করার মাধ্যমে আপনার CI সেটআপকে সহজ করে তোলে।

android {
    testOptions {
        managedDevices {
            devices {
                // Run with ./gradlew nexusOneApi30DebugAndroidTest.
                nexusOneApi30(com.android.build.api.dsl.ManagedVirtualDevice) {
                    device = "Nexus One"
                    apiLevel = 30
                    // Use the AOSP ATD image for better emulator performance
                    systemImageSource = "aosp-atd"
                }
                // Run with ./gradlew  foldApi34DebugAndroidTest.
                foldApi34(com.android.build.api.dsl.ManagedVirtualDevice) {
                    device = "Pixel Fold"
                    apiLevel = 34
                    systemImageSource = "aosp-atd"
                }
            }
        }
    }
}

আপনি টেস্টিং-স্যাম্পলস প্রোজেক্টে GMD-এর একাধিক উদাহরণ খুঁজে পেতে পারেন।

ফায়ারবেস টেস্ট ল্যাব

আপনার পরীক্ষাগুলো এমন নির্দিষ্ট বাস্তব ডিভাইসে চালানোর জন্য ফায়ারবেস টেস্ট ল্যাব (FTL) বা অনুরূপ কোনো ডিভাইস ফার্ম পরিষেবা ব্যবহার করুন, যেগুলোতে আপনার অ্যাক্সেস নাও থাকতে পারে; যেমন বিভিন্ন আকারের ফোল্ডেবল বা ট্যাবলেট। ফায়ারবেস টেস্ট ল্যাব একটি পেইড পরিষেবা, যার একটি ফ্রি টিয়ারও রয়েছে । FTL এমুলেটরেও পরীক্ষা চালানো সমর্থন করে। এই পরিষেবাগুলো ইন্সট্রুমেন্টেড টেস্টিংয়ের নির্ভরযোগ্যতা এবং গতি বাড়ায়, কারণ এগুলো আগে থেকেই ডিভাইস এবং এমুলেটর প্রস্তুত করে রাখতে পারে।

GMD-এর সাথে FTL ব্যবহারের তথ্যের জন্য, "Scale your tests with Gradle-managed devices" দেখুন।

টেস্ট রানার দিয়ে ফিল্টারিং পরীক্ষা করুন

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

আপনি নির্দিষ্ট কিছু টেস্টকে শুধু নির্দিষ্ট ডিভাইসে চালানোর জন্য টীকা যোগ করতে পারেন এবং তারপর টেস্টগুলো চালানোর কমান্ড ব্যবহার করে AndroidJUnitRunner- এ একটি আর্গুমেন্ট পাস করতে পারেন।

উদাহরণস্বরূপ, আপনি বিভিন্ন টীকা তৈরি করতে পারেন:

annotation class TestExpandedWidth
annotation class TestCompactWidth

এবং বিভিন্ন পরীক্ষায় সেগুলো ব্যবহার করুন:

class MyTestClass {

    @Test
    @TestExpandedWidth
    fun myExample_worksOnTablet() {
        ...
    }

    @Test
    @TestCompactWidth
    fun myExample_worksOnPortraitPhone() {
        ...
    }

}

এরপর আপনি টেস্টগুলো চালানোর সময় android.testInstrumentationRunnerArguments.annotation প্রপার্টি ব্যবহার করে নির্দিষ্ট টেস্টগুলো ফিল্টার করতে পারেন। উদাহরণস্বরূপ, যদি আপনি গ্রেডল-পরিচালিত ডিভাইস ব্যবহার করেন:

$ ./gradlew pixelTabletApi30DebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.annotation='com.sample.TestExpandedWidth'

যদি আপনি GMD ব্যবহার না করেন এবং CI-তে এমুলেটর পরিচালনা করেন, তাহলে প্রথমে নিশ্চিত করুন যে সঠিক এমুলেটর বা ডিভাইসটি প্রস্তুত এবং সংযুক্ত আছে, এবং তারপরে ইনস্ট্রুমেন্টেড টেস্টগুলো চালানোর জন্য Gradle কমান্ডগুলোর মধ্যে একটিতে প্যারামিটারটি পাস করুন:

$ ./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.annotation='com.sample.TestExpandedWidth'

উল্লেখ্য যে, এসপ্রেসো ডিভাইস (পরবর্তী অনুচ্ছেদ দেখুন) ডিভাইসের বৈশিষ্ট্য ব্যবহার করে পরীক্ষাগুলো ফিল্টার করতে পারে।

এসপ্রেসো ডিভাইস

যেকোনো ধরনের ইন্সট্রুমেন্টেড টেস্ট, যেমন Espresso, Compose, বা UI Automator টেস্ট ব্যবহার করে, টেস্টের সময় এমুলেটরগুলিতে বিভিন্ন অ্যাকশন সম্পাদন করতে Espresso Device ব্যবহার করুন। এই অ্যাকশনগুলির মধ্যে স্ক্রিনের আকার সেট করা বা ফোল্ডেবল স্টেট বা পসচার টগল করা অন্তর্ভুক্ত থাকতে পারে। উদাহরণস্বরূপ, আপনি একটি ফোল্ডেবল এমুলেটর নিয়ন্ত্রণ করে এটিকে টেবিলটপ মোডে সেট করতে পারেন। Espresso Device-এ নির্দিষ্ট কিছু ফিচার রিকোয়ার করার জন্য JUnit রুল এবং অ্যানোটেশনও রয়েছে:

@RunWith(AndroidJUnit4::class)
class OnDeviceTest {

    @get:Rule(order=1) val activityScenarioRule = activityScenarioRule<MainActivity>()

    @get:Rule(order=2) val screenOrientationRule: ScreenOrientationRule =
        ScreenOrientationRule(ScreenOrientation.PORTRAIT)

    @Test
    fun tabletopMode_playerIsDisplayed() {
        // Set the device to tabletop mode.
        onDevice().setTabletopMode()
        onView(withId(R.id.player)).check(matches(isDisplayed()))
    }
}

উল্লেখ্য যে, এসপ্রেসো ডিভাইস এখনও আলফা পর্যায়ে রয়েছে এবং এর নিম্নলিখিত প্রয়োজনীয়তাগুলো রয়েছে:

  • অ্যান্ড্রয়েড গ্রেডল প্লাগইন ৮.৩ বা উচ্চতর
  • অ্যান্ড্রয়েড এমুলেটর ৩৩.১.১০ বা উচ্চতর
  • অ্যান্ড্রয়েড ভার্চুয়াল ডিভাইস যা এপিআই লেভেল ২৪ বা তার উচ্চতর সংস্করণে চলে

ফিল্টার পরীক্ষা

এসপ্রেসো ডিভাইস সংযুক্ত ডিভাইসগুলির বৈশিষ্ট্যগুলি পড়তে পারে, যা আপনাকে অ্যানোটেশন ব্যবহার করে পরীক্ষাগুলি ফিল্টার করতে সক্ষম করে। যদি অ্যানোটেটেড শর্তগুলি পূরণ না হয়, তবে পরীক্ষাগুলি এড়িয়ে যাওয়া হয়।

RequiresDeviceMode অ্যানোটেশন

RequiresDeviceMode অ্যানোটেশনটি একাধিকবার ব্যবহার করা যেতে পারে এমন একটি টেস্ট নির্দেশ করতে, যা কেবল তখনই চলবে যখন ডিভাইসটিতে সমস্ত DeviceMode ভ্যালু সমর্থিত হবে।

class OnDeviceTest {
    ...
    @Test
    @RequiresDeviceMode(TABLETOP)
    @RequiresDeviceMode(BOOK)
    fun tabletopMode_playerIdDisplayed() {
        // Set the device to tabletop mode.
        onDevice().setTabletopMode()
        onView(withId(R.id.player)).check(matches(isDisplayed()))
    }
}

RequiresDisplay টীকা

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

class OnDeviceTest {
    ...
    @Test
    @RequiresDisplay(EXPANDED, COMPACT)
    fun myScreen_expandedWidthCompactHeight() {
        ...
    }
}

ডিসপ্লেগুলির আকার পরিবর্তন করুন

রানটাইমে স্ক্রিনের আকার পরিবর্তন করতে setDisplaySize() মেথডটি ব্যবহার করুন। এই মেথডটি DisplaySizeRule ক্লাসের সাথে একত্রে ব্যবহার করুন, যা নিশ্চিত করে যে টেস্ট চলাকালীন করা যেকোনো পরিবর্তন পরবর্তী টেস্টের আগে বাতিল হয়ে যায়।

@RunWith(AndroidJUnit4::class)
class ResizeDisplayTest {

    @get:Rule(order = 1) val activityScenarioRule = activityScenarioRule<MainActivity>()

    // Test rule for restoring device to its starting display size when a test case finishes.
    @get:Rule(order = 2) val displaySizeRule: DisplaySizeRule = DisplaySizeRule()

    @Test
    fun resizeWindow_compact() {
        onDevice().setDisplaySize(
            widthSizeClass = WidthSizeClass.COMPACT,
            heightSizeClass = HeightSizeClass.COMPACT
        )
        // Verify visual attributes or state restoration.
    }
}

যখন আপনি setDisplaySize() ব্যবহার করে কোনো ডিসপ্লের আকার পরিবর্তন করেন, তখন ডিভাইসের ডেনসিটিতে কোনো পরিবর্তন আসে না। তাই, যদি কোনো ডাইমেনশন টার্গেট ডিভাইসে ফিট না হয়, তাহলে টেস্টটি একটি UnsupportedDeviceOperationException ত্রুটির সাথে ফেইল করে। এই ক্ষেত্রে টেস্ট রান হওয়া আটকাতে, সেগুলোকে ফিল্টার করে বাদ দেওয়ার জন্য RequiresDisplay অ্যানোটেশনটি ব্যবহার করুন।

@RunWith(AndroidJUnit4::class)
class ResizeDisplayTest {

    @get:Rule(order = 1) var activityScenarioRule = activityScenarioRule<MainActivity>()

    // Test rule for restoring device to its starting display size when a test case finishes.
    @get:Rule(order = 2) var displaySizeRule: DisplaySizeRule = DisplaySizeRule()

    /**
     * Setting the display size to EXPANDED would fail in small devices, so the [RequiresDisplay]
     * annotation prevents this test from being run on devices outside the EXPANDED buckets.
     */
    @RequiresDisplay(
        widthSizeClass = WidthSizeClassEnum.EXPANDED,
        heightSizeClass = HeightSizeClassEnum.EXPANDED
    )
    @Test
    fun resizeWindow_expanded() {
        onDevice().setDisplaySize(
            widthSizeClass = WidthSizeClass.EXPANDED,
            heightSizeClass = HeightSizeClass.EXPANDED
        )
        // Verify visual attributes or state restoration.
    }
}

স্টেটরিস্টোরেশনটেস্টার

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

@Test
fun compactDevice_selectedEmailEmailRetained_afterConfigChange() {
    val stateRestorationTester = StateRestorationTester(composeTestRule)

    // Set content through the StateRestorationTester object.
    stateRestorationTester.setContent {
        MyApp()
    }

    // Simulate a config change.
    stateRestorationTester.emulateSavedInstanceStateRestore()
}

উইন্ডো টেস্টিং লাইব্রেরি

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

উদাহরণস্বরূপ, আপনি একটি কাস্টম FoldingFeature তৈরি করতে FoldingFeature() ফাংশনটি ব্যবহার করতে পারেন, যা আপনি Compose প্রিভিউতে ব্যবহার করতে পারবেন। জাভাতে, createFoldingFeature() ফাংশনটি ব্যবহার করুন।

কম্পোজ প্রিভিউতে, আপনি নিম্নলিখিত উপায়ে FoldingFeature প্রয়োগ করতে পারেন:

@Preview(showBackground = true, widthDp = 480, heightDp = 480)
@Composable private fun FoldablePreview() =
    MyApplicationTheme {
        ExampleScreen(
            displayFeatures = listOf(FoldingFeature(Rect(0, 240, 480, 240)))
        )
 }

এছাড়াও, আপনি TestWindowLayoutInfo() ফাংশন ব্যবহার করে UI টেস্টে ডিসপ্লে ফিচারগুলো অনুকরণ করতে পারেন। নিম্নলিখিত উদাহরণটি স্ক্রিনের কেন্দ্রে একটি HALF_OPENED ভার্টিকাল হিঞ্জ সহ একটি FoldingFeature সিমুলেট করে, এবং তারপর লেআউটটি প্রত্যাশিত কিনা তা পরীক্ষা করে:

রচনা করুন

import androidx.window.layout.FoldingFeature.Orientation.Companion.VERTICAL
import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.testing.layout.FoldingFeature
import androidx.window.testing.layout.TestWindowLayoutInfo
import androidx.window.testing.layout.WindowLayoutInfoPublisherRule

@RunWith(AndroidJUnit4::class)
class MediaControlsFoldingFeatureTest {

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

    @get:Rule(order=2)
    val windowLayoutInfoPublisherRule = WindowLayoutInfoPublisherRule()

    @Test
    fun foldedWithHinge_foldableUiDisplayed() {
        composeTestRule.setContent {
            MediaPlayerScreen()
        }

        val hinge = FoldingFeature(
            activity = composeTestRule.activity,
            state = HALF_OPENED,
            orientation = VERTICAL,
            size = 2
        )

        val expected = TestWindowLayoutInfo(listOf(hinge))
        windowLayoutInfoPublisherRule.overrideWindowLayoutInfo(expected)

        composeTestRule.waitForIdle()

        // Verify that the folding feature is detected and media controls shown.
        composeTestRule.onNodeWithTag("MEDIA_CONTROLS").assertExists()
    }
}

মতামত

import androidx.window.layout.FoldingFeature.Orientation
import androidx.window.layout.FoldingFeature.State
import androidx.window.testing.layout.FoldingFeature
import androidx.window.testing.layout.TestWindowLayoutInfo
import androidx.window.testing.layout.WindowLayoutInfoPublisherRule

@RunWith(AndroidJUnit4::class)
class MediaControlsFoldingFeatureTest {

    @get:Rule(order=1)
    val activityRule = ActivityScenarioRule(MediaPlayerActivity::class.java)

    @get:Rule(order=2)
    val windowLayoutInfoPublisherRule = WindowLayoutInfoPublisherRule()

    @Test
    fun foldedWithHinge_foldableUiDisplayed() {
        activityRule.scenario.onActivity { activity ->
            val feature = FoldingFeature(
                activity = activity,
                state = State.HALF_OPENED,
                orientation = Orientation.VERTICAL)
            val expected = TestWindowLayoutInfo(listOf(feature))
            windowLayoutInfoPublisherRule.overrideWindowLayoutInfo(expected)
        }

        // Verify that the folding feature is detected and media controls shown.
        onView(withId(R.id.media_controls)).check(matches(isDisplayed()))
    }
}

আপনি WindowManager প্রজেক্টে আরও নমুনা খুঁজে পেতে পারেন।

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

ডকুমেন্টেশন

নমুনা

কোডল্যাবস